-
每个函数对象都有一个prototype属性,但普通对象没有prototype属性,prototype下面有一个constructor,指向这个函数
-
每个人对象有一个名为[[prototype]]的内部属性,指向所对应的构造函数的原型对象,原型链基于
__proto__
-
Object Function 互相继承对方,既是函数也是对象
-
属性查找
在访问对象的某个成员的时候会先在对象中找是否存在 如果当前对象中没有就在构造函数的原型对象中找 如果原型对象中没有找到就到原型对象的原型上找 直到 Object的原型对象的原型是null为止
原型链:
谈到继承时,JavaScript 只有一种结构:对象。每个实例对象(object )都有一个私有属性(称之为 proto)指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象 ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
####用原生JS实现new方法
function New(f) {
return function () {
var o = {"__proto__": f.prototype};
f.apply(o, arguments);//继承父类的属性
return o; //返回一个Object
}
}
JavaScript instanceof 运算符代码
instanceof 运算符用于测试prototype属性是否出现在对象原型链中的任何位置
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
var O = R.prototype;// 取 R 的显示原型
L = L.__proto__;// 取 L 的隐式原型
while (true) {
if (L === null)
return false;
if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
return true;
L = L.__proto__;
}
}
继承
// Car.prototype.constructor = Car
// Car.__proto__ = Function.prototype
// Function.__proto__ = Function.prototype
// Object.__proto__ === Function.prototype
// Object.__proto__.__proto__ === Object.prototype
// Object.prototype.__proto__ = null
function Car(color) {
this.color = color;
}
Car.prototype.go = function() {
console.log(this.color)
}
function BMW(color) {
Car.call(this, color);
}
// 可能会改变父类原型
// BMW.prototype = Car.prototype
// call 和 new 会使Car的构造函数执行两遍
// BMW.prototype = new Car()
_proto = Object.create(Car.prototype);
_proto.constructor = BMW;
BMW.prototype = _proto;
// 先继承,在给原型上加BMW的方法
BMW.prototype.come = function() {
console.log('come');
}
var nss = new Car('blue');
// nss.__proto__ = Car.prototype
var wss = new BMW('red');
console.dir(Car);
console.dir(BMW);
console.log('nss', nss);
console.log('wss', wss);