js提供了一些内置类,如Array String Function等,只要有类就有原型。

1,function ,属性包括 arguments, caller,length,name ,prototype,__proto__,

2,prototype,属性又分为constructor: function () {},__proto__: Object,

3,__proto__从别的原型链继承过来可以直接用的,prototype是要加在自己原型链上的,供别人调用,或者直接实例化后,别人可以直接调用转成__proto__的。

__proto__是永远存在的,都指向下一层,最终是Object。

4,function 和prototype本身都含__proto__,其实本身也都是对象,自己继承过来的,他们2个也是基本类型的实例。

 js的instanceof是根据prototype来判断两个对象是否存在继承关系,A instanceof B, js会沿着A的原型链查找 直到找到A.__proto__ === B.prototype 返回true。

 一句话__proto__一层层都是指向继承的,最终到基本类型上。

一,function

function定义的是一个Object(对象),而且还是一个很特殊的对象,这个使用function定义的对象与使用new操作符生成的对象之间有一个重要的区别。

这个区别就是function定义的对象有一个prototype属性,使用new生成的对象就没有这个prototype属性

prototype是function的一个属性。所有通过function 来定义的对象,都有prototype这个属性。

通过{}定义的对象字面量是没有prototype的,如

var a ={1:"a"}
console.log (a.prototype);

 结果是undefined,原因是他已经实例化,

var a ={1:"a"}
console.log (a.__proto__);

结果是 Object {} ,相当于new 后的。

function  的length 参考http://www.cnblogs.com/52cik/p/js-function-length.html

函数的 length 属性只能得到他的形参个数,而无法得知实参个数。

function 是Object的实例,他自己的__proto__是Object.prototype

var A =function (age ){
this.age = age;
}
A.prototype.haha = function (){}
console.log( A instanceof Object)// true
console.log( typeof A) // function
console.log (Object.prototype.toString.call(A)) //[object Function]

  

数组类型typeof 是object,数组跟object更加接近

var B =[1,2,3]
console.log(typeof B)//object
console.log(typeof A)//function

 

var A =function (age ){
this.age = age;
}
A.prototype.haha = function (){}
var B =[1,2,3]
console.log(typeof A)//function
console.log(A instanceof Function)//true
console.log(A instanceof Object)//true
console.log(typeof B)//object
console.log(B instanceof Array)//true
console.log (Object.prototype.toString.call(A)) //[object Object]

caller:

返回一个对函数的引用,该函数调用了当前函数。
   functionName.caller 
   functionName 对象是所执行函数的名称。
  说明
   对于函数来说,caller 属性只有在函数执行时才有定义。如果函数是由顶层调用的,那么 caller 包含的就是 null 。如果在字符串上下文中使用 caller 属性,那么结果和 functionName.toString 一样,也就是说,显示的是函数的反编译文本。

var A =function (age ){
this.age = age;
console.log(A.caller)
}
A.prototype.haha = function (){}
var B = function(type){
A();
}
B();

  返回,最后是B的函数,谁调用我了,返回谁

function (type){
A();
}

arguments.callee :返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文。

[function.]arguments.callee
          可选项 function 参数是当前正在执行的 Function 对象的名称。

说明 : callee 属性的初始值就是正被执行的 Function 对象。

callee 属性是 arguments 对象的一个成员,它表示对函数对象本身的引用,这有利于匿名函数的递归或者保证函数的封装性,例如下边示例的递归计算1到n的自然数之和。而该属性仅当相关函数正在执行时才可用。还有需要注意的是callee拥有length属性,这个属性有时候用于验证还是比较好的。arguments.length是实参长度,arguments.callee.length是
    形参长度,由此可以判断调用时形参长度是否和实参长度一致。

二、prototype

本身含constructor,__proto__ 
var A =function (age ){
this.age = age;
}
A.prototype.haha = function (){}
console.log (A.prototype) ;

可以看到的内容

Object {haha: function}
constructor: function (age ){
arguments: null
caller: null
length: 1
name: ""
prototype: Object
__proto__: function Empty() {}
<function scope>
haha: function (){}
__proto__: Object
constructor实际指向的是 函数创建时的那个function。
function Animal(name) {
this.name = name;
}
Animal.prototype = {
talk: function() {},
run: function() {}
}
function Dog(age,name) {
//Animal.call(this,name)
this.age=age;
}
// 要让 Dog 继承 Animal, 只需:__ 2个_
Dog.prototype = new Animal ; // 实例化后
Dog.prototype.constructor = Dog;//手工的把constructor给暴露出来了。可以通过dog.constructor来调用
//Dog.prototype = new Animal ; //Animal的构造函数和自己的prototype也都放到Dog上
Dog.prototype.haha = function () {};//
Dog.prototype.haha.tata = 4;
var dog = new Dog("sdd","bbb");
var animal = new Animal("aaaa");
console.log(dog);
console.log(Dog.prototype);

  返回结果如下:

dog.__proto__.__proto__ === Animal.prototype 返回的true。

原型链作为实现继承的主要方法,其基本思想是:让原型对象等于另一个类型的实例,这样原型对象将包含一个指向另一个原型的指针,相应的,另一个原型中也包含着一个指向另一个构造函数的指针,假如另一个原型又是另一个类型的实例,如此层层递进,就构成了实例与原型的链条,这个链条就称之为原型链.

另外一个问题,prototype是存储放到共享区域内的,可以共同修改。

Dog.prototype = Animal.prototype的方法集成,如果子类重写了父类的方法,父类也会受到影响。

推荐的用法是

Dog.prototype.__proto__ = Animal.prototype

不用写Dog.prototype.constructor = Dog了,constructor 没有被覆盖,Dog本身就有了。

参考可以看下下面的例子,   http://www.cnblogs.com/qiantuwuliang/archive/2011/01/08/1930548.html

代码 

function Person(name)
{
this.name=name;
this.showMe=function()
{
alert(this.name);
}
}; Person.prototype.from=function()
{
alert('I come from prototype.');
}
var father=new Person('js');//为了下面演示使用showMe方法,采用了js参数,实际多采用无参数
alert(father.constructor);//查看构造函数,结果是:function Person(name) {...};
function SubPer()
{
}
SubPer.prototype=father;//注意这里
SubPer.prototype.constructor=SubPer; var son=new SubPer();
son.showMe();//js
son.from();//I come from prototype.
alert(father.constructor);//function SubPer(){...}
alert(son.constructor);//function SubPer(){...}
alert(SubPer.prototype.constructor);//function SubPer(){...}

  

关于prototype是共享和prototype的作用域问题

function Tree(x){
this.value = x;
}
Tree.prototype.children = [1,2]; var a =new Tree(2);
a.children=3;
var b = new Tree(4);
b.children=5;
var c = new Tree(6); 
console.log (c.children)//[1,2]

 这个对 a.__proto_ 没有做修改,最后依然是 a.__proto_ === Tree.prototype

a.children=3,相当于在a这个对象下面直接加了个children的属性。

function Tree(x){
this.value = x;
}
Tree.prototype.children = [1,2]; var a =new Tree(2);
a.children.push("3");
var b = new Tree(4);
b.children.push("5");
var c = new Tree(6); 
console.log (c.children);//[1,2,"3","5"]

  a.children相当于开始是undefined,如果直接复制的话,就是在a对象下加属性了,然后在.操作,相当于从原型链上去取了。

var A = function(b){
this.b =b;
}
A.prototype.hh="222"; $.extend(A.prototype,{
b:"333",
hh:"444"
});
var a = new A();
console.log(a);

  

A
  1. b: undefined
  2. __proto__: Object
    1. b: "333"
    2. constructor: function (b){
      1. arguments: null
      2. caller: null
      3. length: 1
      4. name: ""
      5. prototype: Object
      6. __proto__: function Empty() {}
      7. <function scope>
    3. hh: "444"
    4. __proto__: Object

最新文章

  1. docker&#39;部署
  2. SQL基础之XML
  3. Linux/CentOS 同步网络时间
  4. 浩瀚科技PDA移动开单|盘点机 数据采集器 条码扫描开单微POS软件 现场打印开单
  5. OpenGL的glTexImage2D()与gluBuild2DMipmaps()的使用方法及区别
  6. PDF 补丁丁 0.4.3.1582 测试版发布:修复上一测试版的问题
  7. 程序员的出路在哪里?挣钱的机会来了续-福利来了,仿QQ界面,放出全部源码,打造创业框架及实现思路
  8. swift函数和初始化控件(// MARK:分割线)
  9. HTTP Post请求过程详解
  10. winform 映射字段的写法:
  11. RegexOne
  12. Android handler 报错处理Can&#39;t create handler inside thread that has not called Looper.prepare()
  13. 【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
  14. POJ 1734 求最小环路径 拓展Floyd
  15. webapp 微信开发适配问题
  16. Hibernate Session &amp; Transaction详解
  17. JS采用ActiveXObject实现用户在提交表单时屏蔽敏感词的功能
  18. Spring之bean二生命周期
  19. 爬取豆瓣电影影评,生成wordcloud词云,并利用监督学习根据评论自动打星
  20. 吴恩达机器学习笔记43-SVM大边界分类背后的数学(Mathematics Behind Large Margin Classification of SVM)

热门文章

  1. codeforces 149D Coloring Brackets (区间DP + dfs)
  2. PWA之push服务
  3. jmeter压测--从文本中读取参数
  4. P1720 月落乌啼算钱
  5. 【前端】模拟微信上传图片(带预览,支持预览gif)
  6. logging模块基础
  7. 洛谷P1251 餐巾计划问题(最小费用最大流)
  8. 【学习笔记】深入理解js原型和闭包(14)——从【自由变量】到【作用域链】
  9. 洛谷 P2580 于是他错误的点名开始了
  10. Django展示第一个网页