谈谈你对js原型的理解:
js没有类继承机制,它是靠原型机制来实现继承的。比如Person对象有一个Person.prototype原型,当无法修改Person的构造函数时,可以通过Person.prototype让所有的Person实例都具有某一属性或方法。由于所有实例都共享同一prototype对象,从外界看来,prototype对象是实例对象的原型,实例对象继承了prototype对象。
我们通过代码来理解js的原型机制:
第一部分代码:
function Person(name,age){
this.name = name;
this.age = age;
this.show = function(){
console.log("I am a person");
}
}
var p1 = new Person("javascript",23);
console.log(p1.name); //javascript
console.log(p1.age); //23
console.log(p1.prototype); //undefined
console.log(Person.prototype);
这段代码的运行结果是:
通过代码的运行结果可以得出:
console.log(p1.prototype);
//undefined,说明new出来的实例对象是没有原型的。
console.log(Person.prototype);
//Object
这里我总结了3条重要的知识点:
1. 每一个通过function定义的对象都有一个prototype原型属性,这个属性是一个对象;
2. 原型对象prototype有一个constructor属性,这个属性指向原型对象所属的构造函数;
3. 实例对象都有一个proto属性,这个属性指向构造函数的原型对象。
第二部分代码:
function Person(name,age){
this.name = name;
this.age = age;
this.show = function(){
console.log("I am a person");
}
}
var p1 = new Person("javascript",23);
console.log(p1.__proto__); //Object
console.log(p1.constructor);
console.log(p1.__proto__ == Person.prototype); //true
这段代码的运行结果为:
通过代码的运行结果可以得出:
p1.proto == Person.prototype //true
为true的原因:在js中,每个函数都有一个prototype属性,当一个函数被用作构造函数来创建实例时,该函数的prototype属性值将被作为原型赋值给所有实例对象(即设置实例对象的proto属性)。所以说,所有实例的原型引用的是函数的prototype属性。
prototype的作用:
prototype属性可以为一个类动态地添加属性和方法;
prototype应用到的情形:当新创建多个实例时,这些实例的属性可以改变,但这些实例所拥有的方法都是一样的,我们不可能在创建100个实例时,这些实例的方法也被创建100次,这样很可能导致内存的溢出。为了只创建一次方法,可以使用prototype。
1. prototype与_proto_的区别
prototype是构造函数的属性,proto是实例对象的属性,这两者指向同一个对象。
2. 构造函数
function Person(name){
this.name = name;
}
var p1 = new Person("Zhang");
var p2 = new Person("Wang");
console.log(p1.constructor == Person); //true
console.log(p2.constructor == Person); //true
实例的构造函数属性(constructor)指向构造函数。
3. 举一个简单例子的原型链
function Person(){}
Person.prototype.name="abc";
var obj = new Person();
console.log(obj.name); //abc
obj对象的原型链:
obj—->Person.prototype—->Object.prototype—->null
当执行obj.name时,obj首先会查找自己是否具有name属性;如果没有,就会沿着原型链依次去查找…
所有实例对象的属性和方法一般分为两种:一种是自身的,一种是引用自prototype。每当需要读取某个对象的某个属性时,首先会在对象实例中查找,如果找到,就返回该属性的值,如果没有,就会去原型对象中找,依次沿着原型链向上…