您的位置:首页 > 其它

彻底理解原型、原型链、new操作符、prototype、__proto__、constructor等属性的概念

2016-12-16 12:28 645 查看
看过网上很多类似的文章, 我还要写这篇文章的目的一是加深自己的印象,二是让读者用更加易懂的方式去理解这几个概念。(如果还是不理解,那是我的错。。毕竟我也只是在一个较浅的层面去理解的)

原型和原型链

函数的prototype属性和对象的__proto__属性

构造函数

new操作符

constructor属性

首先给出几个理论概念:

原型和原型链

在JS中,万物皆对象。但是对象不是凭空产生的,而且对象有自己与生俱来的属性和方法,而这些属性和方法都是从它们的原型中继承而来的(继承的概念在另一篇文章会详细介绍),可以理解为儿子继承父亲的财产? 每个对象的
__proto__
属性 就是一个指向它们的原型的一个指针,它们的原型也是对象,也有
__proto__
属性指向它的原型,这样就构成了原型链,最终的原型对象就是object对象,也就是说 任何对象它们的原型链的最顶端都是object对象。 这个object对象的
__proto__
属性值为null;

函数的prototype属性和对象的__proto__属性

函数的prototype属性

只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。

引用自《JavaScript高级程序设计》

对象的
__proto__
属性

即一个对象的原型对象

接下来看个例子,并解释构造函数与new操作符以及
__proto__
属性和prototype属性的区别:

var Fn = function(){
//函数体
};
var p = new Fn();


定义了一个构造函数 Fn,它当然也是一个函数,是Function类型的实例

变量p是通过 new操作符 + Fn()构造函数 创建的一个实例对象。

构造函数

构造函数默认首字母大写,ECMAscript中​内置的构造函数有 Array(),String(),Function(),Object()….

也可以自己创建构造函数,如上面例子

若直接调用构造函数时,与普通函数没有区别

若加上new操作符调用时,情况就略为复杂了,请往下看

new操作符

new会自动创建this对象,且类型就是构造函数对应的类型。(Array()的话就是array类型的对象,上述例子是object类型)

创建一个空对象 p = {} ,它是object的实例

设置p的原型链 p.
__proto__
=Fn.prototype; //Fn.prototype为构造函数的原型对象

Fn的this就指向了p,执行Fn的函数体

判断Fn的返回值类型:

如果是值类型,就丢弃它,还是返回p对象

var Fn = function(){
this.name = 'xiaoming';
return this.name;
};
var p = new Fn();
console.log(p);//控制台返回  Fn {name: "xiaoming"}  这里的Fn意思是通过Fn构造函数创建的实例 ,可以看到返回的是创建的p对象


如果是引用类型,就返回这个引用类型的对象,替换掉p

var Fn = function(){
this.name = 'xiaoming';
return this.__proto__;
};
var p = new Fn();
console.log(p);//控制台返回  Object {} 。首先this成了p对象,但是Fn构造函数返回的不是this,而是返回this也就是p对象的__proto__属性,这个属性指向了他的原型对象也就是Object()构造函数创建的object对象,它是一个引用类型,它替换掉了p! 因此这里的变量 p 是一个指针,指向它的原型

console.log(Fn.prototype == p) //返回true,因为Fn构造函数的原型和p指针此时指向p.__proto__,是同一个对象


这个例子很好地解释了new操作符、构造函数、prototype属性、proto属性。 我自己是这么认为的^^

constructor属性

constructor属性返回对创建此对象的数组函数的引用。

var Fn = function(){
this.name = 'xiaoming';
};
var p = new Fn;
var arr = new Array();
console.log(arr.constructor);  //function Array(){[native code]};返回是内置的Array()构造函数 native code 为程序自带的,是二进制编译的无法显示出来代码,是直接编译成了机器可识别并运行的语言

console.log(Fn.constructor);  //function Function(){[native code]};

console.log(Fn.prototype.constructor);  //function(){this.name = 'xiaoming';}

console.log(p.constructor);   //function(){this.name = 'xiaoming';}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息