Prototype属性是javascript为每个Function实例创建的一个对象。Prototype属性来自Function构造函数,Function构造函数为每个实例赋一个prootype属性
var myFunction = function() {}; console.log(myFunction.prototype);//输出myFunction{} //默认的prototype属性是Object对象 console.log(typeof myFunction.prototype); //输出object myFunction.prototype = {}; //设置prototype属性为空对象 console.log(myFunction.prototype);//输出空对象,object{}
例如:因为在myArray.foo,Array.prototype.foo,Object.prototype.foo中没有找到foo,所以foo是undefined,所以最后输出的是undefined
var myArray = {}; console.log(myArray.foo);//输出undefined,
与作用域链一样,原型链在查找时将使用它找到的第一个值
查找的顺序为:自身对象----〉构造函数----〉Object对象
如下例子查找顺序为:myArray.foo->Array.prototype.fooàObject.prototype.foo
Object.prototype.foo = "object-foo"; Array.prototype.foo = "array-foo"; var myArray = []; console.log(myArray.foo); //输出array-foo myArray.foo = "bar"; console.log(myArray.foo);//输出bar
可以用一个新值来替换prototype属性的默认值,但是这样会删除原型对象中的默认得constructor属性,除非手动指定一个。
var foo = function Foo() { }; foo.prototype = {}; var fooInstance = new foo(); console.log(fooInstance.constructor === foo); //输出false,破坏了引用 console.log(typeof fooInstance.constructor); //输出function foo.prototype = { constructor: foo }; //重新指定 console.log(fooInstance.constructor === foo); //输出false,因为fooInstance在重新指定之前已经实例化,所以取不到最新值 console.log(typeof fooInstance.constructor); //输出function var bar = new foo(); console.log(bar.constructor === foo);//输出true console.log(typeof bar.constructor); //输出function
实例总是能够从原型获得最新的值,不管何时被实例化,更改或附加,在这种意义上,prototype属性是动态的。
var foo = function Foo() { }; foo.prototype.x = 1; var fooInstance = new foo(); console.log(fooInstance.x);//输出1 foo.prototype.x = 2; console.log(fooInstance.x);//输出2 console.log(foo.x);//输出undefined 通过替换默认原型对象的方式赋值,例如: var foo = function Foo() { }; foo.prototype={x:1} var fooInstance = new foo(); console.log(fooInstance.x);//输出1 foo.prototype.x = 2; console.log(fooInstance.x);//输出2 console.log(foo.x);//输出undefined
又例如:
var foo = function Foo() { }; foo.prototype={x:1} var fooInstance = new foo(); console.log(fooInstance.x);//输出1 foo.prototype={x:2} console.log(fooInstance.x);//输出1,因为fooInstance对象在原型foo.prototype={x:2}之前,所以获取不到最新的原型值 console.log(foo.x);//输出undefined
创建一个实例时,该实例将在实例化时被绑定到“刚完成”的原型。
提供一个新对象做为prototype属性不会更新已创建实例和原型之间的连接。
例如:
var foo = function Foo() { }; foo.prototype.x = 1; var fooInstance = new foo(); console.log(fooInstance.x); //输出1 //使用新Object()对象覆盖Foo的原型 foo.prototype = { x: 2 }; console.log(fooInstance.x);//输出1,fooInstance依然是引用的初始化的原型对象 //该新实例目前引用的就是新原型对象了(也就是{x:2}) var newFoolInstance = new foo(); console.log(newFoolInstance.x); //输出2
一旦开始创建实例,就不应用一个新对象来替换对象的原型
//用户自定义构造函数像原生构造函数一样原型继承 var Person = function() { }; Person.prototype.legs = 2; Person.prototype.arms = 2; Person.prototype.countLimbs = function() { return this.legs + this.arms; }; var chuck = new Person(); console.log(chuck.countLimbs());//输出4 //为了很好的展示原型链,可以创建一个构造函数,通过给构造函数传值,而覆盖原型的值 var Person = function(legs, arms) { //隐藏原型的值 if (legs != undefined) { this.legs = legs; } if (arms != undefined) { this.arms = arms; } }; Person.prototype.legs = 2; Person.prototype.arms = 2; Person.prototype.countLimbs = function() { return this.legs + this.arms; }; var chuck = new Person(0, 0); console.log(chuck.countLimbs());//输出0
只需 要将对象实例做为要继承该对象实例的函数的prototype的属性值
例如:chef对象需要继承Person(),只需要将chef.prototype指向实例化的Person()
即:chef.prototype=new Person();
//创建继承链 var Person = function() { this.bar = ‘bar‘; }; Person.prototype.foo = "foo"; var chef = function() { this.goo = "goo"; }; chef.prototype = new Person(); //创建继承 var cody = new chef(); console.log(cody.foo); //输出foo console.log(cody.goo); //输出goo console.log(cody.bar);//输出bar
原文:http://www.cnblogs.com/alice626/p/5210907.html