一、prototype、__proto__与constructor
prototype:显式原型
__proto__:隐式原型
constructor:在Javascript语言中,constructor属性是专门为function而设计的,它存在于每个function的prototype属性中,这个constructor保存指向function的一个引用
__proto__属性是对象所独有的,prototype属性是函数所独有的,但由于JS中函数也是一种对象,所以函数也有__proto__属性
原型:每个函数都具有prototype属性,它被默认成一个对象,即原型对象,原型对象的用途是包含所有实例共享的属性和方法
原型链:当对象使用属性时,先在自身找,有就直接用,没有就沿着__proto__这条链往上找,直到Objetc原型的位置,有就返回相应的值,没有就返回underfined
二、new操作符
new操作符具体干了三件事
var
obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
对于Base.call(obj),如果Base(),Base函数中的this表示windows;如果Base.call(obj),call函数指定Base函数中的this,使得this为obj,在Base中为obj添加属性和方法
三、测试代码
栗子1
Person.prototype.constructor == Person
p.__proto__ == Person.prototype
function Person(age) {
this.age = age;
}
Person.prototype.gender = 'male'; // 在Person的prototy上,在p的__proto__上
var p = new Person(10);
console.log(p.age); // 10
console.log(p.gender); // male
console.log(Person.prototype.constructor == Person); // true
console.log(p.__proto__ == Person.prototype); // true
var p1 = new Person(20);
// new操作符具体干了三件事
var p2 = {};
p2.__proto__ = Person.prototype;
Person.call(p2, 30);
console.log(p1); // Person { age: 20 }
console.log(p2); // Person { age: 30 }
函数Person与对象p:
栗子2
function Animal() {
this.gender = "male";
}
Animal.prototype.age = "10";
function Person() {
this.name = "zz";
}
Person.prototype = new Animal();
Person.prototype.tel = "123456";
var p = new Person();
console.log(p);
/**
* prototype是函数对象所有的
* 等价于
* 1. var p = {};
* 2. p.__proto__ = Person.prototype = new Animal();
* 2.1. p.__proto__ = {};
* 2.2. p.__proto__.__proto__ = Animal.prototype;
* 2.3. Animal.call(p.__proto__); // call内部执行的是 p.__proto__.gender = "male"
* 3. Person.call(p); // call内部执行的是p.name = "zz"
*
* 结果
* p.name = "zz"
* p.__proto__ = Person.prototype
* p.__proto__.tel = "123456"
* p.__proto__.gender = "male"
* p.__Proto__.__proto__ = Animal.prototype
* p.__proto__.__proto__.age = "10"
* p.__proto__.__proto__.__proto__ = Object.prototype
* p.__proto__.__proto__.__proto__.__proto__ = null
*
*/