原型链
js是一种面向对象的语言,js里的任何东西都是对象,所以需要一种机制来联系这些对象
,因此”继承”的思想就能够联系这些对象.
在Js中使用new命令,从原型对象生成一个实例对象,new后面跟的是构造函数
例如现在有个Dog的构造函数
function Dog(name){
this.name = name;
}
//对这个构造函数使用new,就会生成一个狗对象的实例
var dog = new Dog("大黄");
console.log(dog.name);
//这里构造函数中的this指的是新创建的实例对象dog。
//谁调用我,我就代表谁.
new运算符的缺点
用构造函数生成实例对象,有个缺点是无法共享属性和方法.
比如,在Dog对象的构造函数中,设置一个实例对象的共有属性speices
function Dog(name){
this.name = name ;
this.specices ="犬科";
}
//生成两个实例对象
var dogA = new Dog("大黄");//默认会自动执行Dog("大黄")这个构造函数
var dogB = new Dog("阿拉斯加");
这两个对象都是独立的, 修改一个并不会影响到另一个对象.
dogA.specices = "猫科";
console.log(dogB.specices);//犬科
每个实例对象,都有自己的属性和方法的副本。无法做到数据共享,极大地浪费了资源
这时prototype属性的引入至关重要
要是能共享属性和方法该有多好呢,于是决定为构造函数设置一个prototype属性
这个属性包含一个对象(prototype对象),所有实例对象需要共享的属性和方法,所有要共享的属性和方法都放在这个对象(prototype)里面,那些不用共享的属性和方法就放在构造函数里面。
实例对象一旦创建,将自动引用prototype对象的属性和方法。也就是说实例对象的属性和方法有两种,一种是本地的,一种是引用的.
function Dog(name) {
this.name = name;
}
Dog.prototype = {
species : "犬科",
}
var dogA = new Dog("大黄");
var dogB = new Dog("阿拉斯加");
Dog.prototype.constructor === Dog;//true;
dogA.__proto__.constructor === Dog;//true;
alert(dogA.species);//犬科
alert(dogB.species);//犬科
now,species属性放在prototype对象里,是两个实例共享的,因此改变
Dog.prototype.species = "猫科";
alert(dogA.species);//猫科
alert(dogB.species);//猫科
总结
由于所有的实例对象共享一个prototype对象,因此从外界看来,prototype对象好像是实例对象的原型,而实例对象好像继承了prototype对象一样.
js中proto 和prototype的区别和关系
proto (隐式原型)与prototype(显式原型);
显示原型prototype
每个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向函数的原型对象.
通过Function.prototype.bind方法构造出来的函数是个例外,他没有prototype属性
隐式原型proto, 前后都是两个_
js中任意对象都有一个内置属性[[prototype]],在ES5之前没有标准的方法访问这个内置属性,但是在大多数浏览器都有支持通过_proto_来访问,ES5中有了这个内置属性标准的Get方法Object.getPrototypeOf()
Object.prototype这个对象是个例外,他的 proto 值为null
隐式原型指向创建这个对象的函数(constructor)的prototype,
即指向创建这个对象的函数的显示原型,因此关键点在于找到创建这个对象的构造函数,那么js创建对象的方式有三种:
(1)对象字面量的方式var obj={};这是语法糖的方式创建的对象
(2)new 方式创建 var o = new Object();
(3)ES5中的Object.create() 创建的对象没有构造函数
function object(o){
function F () {};
F.prototype = o;
return new F();
}
console.log(dog. proto === Dog.prototype) ; //true
function Dog (name) {
this.name = name;
}
Dog.prototype = {
species : "犬科",
getName : function(){
return this.name;
}
}
var dog = new Dog("大黄");
dog.name;//'大黄'
dog.getName();//'大黄'
dog.species ;//"犬科"
console.log(dog.__proto__ === Dog.prototype) ; //true
他们的作用
显式原型prototype 的作用 : 基于原型的继承和属性与方法的共享.
隐式原型的作用:
构成原型链,同样用于实现基于原型的继承.当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着proto依次查找。
function Dog(name){
this.name = name;
}
Dog.prototype.species = "中华田园犬";
var dog = new Dog("大黄");
![图片描述][1]
一,构造函数的显示原型的隐式原型
内建对象(built-in object):比如Array(), Array.prototype是一个对象,它是由Object()这个构造函数创建的,所以 Array.prototype. proto === Object.prototype;//{} 空对象; 也就是说所有的内建对象都是由Object()函数创建的。
function Object ( ) {
}
function Array ( ) {
}
Array.prototype = new Object ();
Array.prototype.__proto__ === Object.prototype;//true
二,自定义对象,也是由Object()函数创建的
function Object () {
}
function Fun () {
}
var fun = new Fun();
Fun.prototype.__proto__ === Object.prototype;//true
三,构造函数的隐式原型
既然是构造函数那么他是Function ( )的实例,因此也就指向Function.prototype,
也就是说 Fun.proto === Function.prototype;
function Fun ( ) {
}
var fun = new Fun();
Fun.__proto__ === Function.prototype;//true;
instanceof
instanceof操作符的内部实现机制和隐藏原型,显式原型有直接关系, instanceof的左值一般为对象,右值为一个构造函数,用来判断左值是否是右值的实例。它实现的原理:
obj instanceof Fun;
obj.__proto__.__proto__... === Fun.prototype //为true还是false;
//就是obj沿着__proto__一直寻找直到原型链的末端。
Function instanceof Object; // true;
Function instanceof Function //true
Object instanceof Function //true
Object instanceof Object //true
那么Object和Function的关系是什么呢?
Object.__proto__.construtor
//function Function (){ [native code] }
Function.__proto__.constructor
//function Function () { [native code] }
Object.__proto__
//function () { }
Function.__proto__
//function () { }
Object.__proto__ === Function.__proto__;//true
Object.prototype.__proto__ === null; //true
Function.prototype.__proto__ === Object.prototype;//true 都为 {}
热门评论
Object.__proto__ == Function.prototype // true
也就是说Object对象是由 Function 构造函数创建的
文章中第三段带有有错误 Dog.prototype = { species : "犬科"} 应改为 Dog.prototype.species="犬科"
有错的话,欢迎指点改正。