原型和原型链,大致能够用如下几条规则归纳,弄清楚了这几条,也就基本吃透了原型和原型链。函数
(为了方便起见,下文中__proto__用隐式原型代替,prototype用显式原型代替)
举个栗子:this
// 构造函数 function Human(name) { this.name = name; } Human.prototype.introduce = function(){ console.log('My name is', this.name); } var somebody = new Human('somebody'); console.log(Human.prototype); // Function console.log(Human.prototype.constructor === Human); // true console.log(somebody.__proto__ === Human.prototype); // true somebody.introduce(); // "My name is somebody"
在上述例子中,Human是构造函数,而somebody是Human的一个实例。从console输出结果能够验证,构造函数的显式原型的constructor属性指向它自己,实例的隐式原型属性指向其构造函数的显式原型。spa
在实例somebody中并无introduce方法,该方法实际是在Human.prototype中,由上述第四条,当试图获得一个对象的某个属性值时,若是这个对象自己没有该属性,就会去它的__proto__(它构造函数的prototype)中查找,因此somebody的introduce方法其实是somebody.__proto__.introduce,也就是Human.prototype.introduce。prototype
上图帮助理解吧~code
实例的隐式原型属性指向其构造函数的显式原型属性。
全部的一层一层的__proto__连起来,就构成了原型链。例如,在Object.prototype上有一方法toString,而somebody也有,但其实somebody的toString方法并不是自身全部(除非单独有声明),而是来自于somebody.__proto__.__proto__.__proto__(即Object.prototype),这一点能够经过hasOwnProperty证实。对象
判断一个对象是否在原型链上能够用instanceof,判断某一个属性是不是自身属性能够用hasOwnProperty。blog
console.log(somebody.hasOwnProperty('name')) // true console.log(somebody instanceof Object); // true //语法 // obj.hasOwnProperty(prop) // object instanceof constructor
后续再出一期与new运算符相关的还有与原型继承、class相关的吧,排期ing。继承