Object.prototype 原型和原型链
Object.prototype 原型和原型链
原型
Javascript中所有的对象都是Object的实例,并继承Object.prototype的属性和方法,有些属性是隐藏的。换句话说,在对象创建时会存在预定义的属性,其中有一个属性就是原型对象。在函数对象中存在原型对象prototype,在普通对象中没有prototype
,但存在__proto__
。或者说使用function定义的对象与使用new操作符生成的对象之间有一个重要的区别,这个区别就是function定义的对象有一个prototype属性,使用new生成的对象就没有这个prototype属性,存在__proto__
。
var o =new Object();
console.log(o.__proto__);
console.log(o.prototype);//undefined
var fn = function(){}
console.log(fn.prototype);//Object {constructor: function}
var f1 = new fn();
console.log(f1.__proto__);
console.log(f1.__proto__===fn.prototype);//true
原型链
那么__proto__
是什么?每个对象都会在其内部初始化一个属性,就是__proto__
。
普通对象中的__proto__
是什么呢? Object的本质函数对象,是通过new Function()创建,所以Object.__proto__
指向Function.prototype
。同理,Function也是函数对象,因此Function.__proto__
同样指向Function.prototype
。 Object.prototype
对象也有__proto__
属性,但它比较特殊,为null。这个由__proto__
串起来的直到Object.prototype.__proto__
为null的链就是原型链。
console.log(Object.__proto__ === Function.prototype);//true
console.log(Function.__proto__===Function.prototype);//true
console.log(Object.prototype.__proto__);//null
当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__
里找这个属性,这个__proto__
又会有自己的__proto__
,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。参考下面的例子:
var Fn = function(){};
Fn.prototype.Hello = function(){
console.log("Hello World");
}
var f1 = new Fn();
f1.Hello();//Hello World
首先var f1=new fn(),f1是Fn的实例,可以得出f1.__proto__=Fn.prototype
。当我们调用f1.hello()
时,首先f1中没有Hello
这个属性,于是,它会到他的__proto__
中去找,也就是Fn.prototype
,而我们在上面定义了 Fn.prototype.Hello=function(){}; 于是,就找到了对应的方法。
从一个更复杂的例子中看原型链的原理:
var Person = function() {};
Person.prototype.Name = function() {
console.log("person name");
}
Person.prototype.Sex = "male or female";
var Younger = function() {};
Younger.prototype = new Person();
Younger.prototype.Age = function() {
console.log("14-28")
};
Younger.prototype.Sex = "female";
var Ann = new Younger();
Ann.Name(); //person name
console.log(Ann.Age()); //14-28
console.log(Ann.Sex); //female
对上述代码,我们可以进行如下分析:
var Younger = function() {}
=>:Younger.__proto__=Person.prototype
,
Younger.prototype = new Person()
=>:Younger.prototype.__proto__ = Person.prototype
,
var Ann = new Younger()
===>Ann.__proto__=Younger.prototype
,
综上可得:
Ann.__proto__.__proto__ = Person.prototype
Ann
本身没有Name()
方法,于是从Ann.__proto__
(Younger.prototype
)中找,仍没有找到于是在向上一层Ann.__proto__.__proto__
(Person.prototype
)中寻找,最终在Person.prototype
中找到对应的方法并调用。
同理,Ann
本身并没有Age()
方法,但在Ann.__proto__
(Younger.prototype
)存在。
对于Ann.Sex
,在Ann.__proto__
(Younger.prototype
)中已经能够找到,便不再向上寻找,因此输出是female
。
最新文章
- 为Xamarin更好的开发而改写的库
- fifo write
- Scala入门
- Install Apache, PHP And MySQL On CentOS 7 (LAMP)
- POJ-3648 Wedding 2sat
- BZOJ1345: [Baltic2007]序列问题Sequence
- 中国版 Azure 现提供 Azure Traffic Manager
- [C++程序设计]用函数指针变量调用函数
- UVA 10129 Play on Words
- hdu_2608_0 or 1_数论
- POJ-1273-Drainage Ditches(网络流之最大流)
- windows动态库与Linux动态库
- 《Apache kafka实战》读书笔记-管理Kafka集群安全之ACL篇
- AtCoder Grand Contest 1~10 做题小记
- supervisord.conf
- Good Bye 2016 F.New Year and Finding Roots(交互)
- 用instr 直接取最右端的点的位置:
- Redis主从同步及哨兵原理
- beat冲刺(5/7)
- 20159212杨翔实验一(熟悉Java开发环境)实验报告