JS:构造函数、原型、new

构造函数、原型对象、实例

1、每个函数都有一个prototype属性,该属性指向函数的原型对象,原型对象的用途是可以让所有对象实例共享它所包含的属性和方法。

2、默认情况下,每个原型对象都会自动获得一个constructor属性,该属性指向prototype属性所在的函数。constructor属性最初是用来标识对象类型的,但检测对象类型,还是instanceof更可靠些(因为对象的constructor可被改写,指向的函数不同于原型对象construtor指向的函数):

person1 instanceof Person // 检测Person.prototype是否在person1的原型链上,在就返回true。

3、当调用构造函数创建一个对象实例后,该实例的内部将包含一个指针[[Prototype]](内部属性),指向构造函数的原型对象。Firefox、Safari和Chrome等浏览器在每个对象上都加了一个__proto__,来访问[[Prototype]],而在其他实现中,这个属性则完全不可见。对象实例和构造函数没有直接关系。可以通过isPrototypeOf()来确定是否为对象的原型对象:

Person.prototype.isPrototypeOf(person1);

ES5中增加了新方法Object.getPrototypeOf(),返回[[Prototype]]的值(IE 9+,Firefox 3.5+,Safari 5+,Opera 12+,Chrome):

Object.getPrototypeOf(person1) === Person.prototype // true

4、读取对象某个属性时,会先搜索该对象实例,如果找到同名属性,返回该属性值;如果没有找到,继续搜索该对象的原型对象,这是多个对象实例共享原型对象属性和方法的基本原理。对象实例中的属性会屏蔽原型对象中的同名属性,使用delete操作符可以删除实例属性,从而能重新访问原型中的属性。

function Person() {}
Person.prototype.name = 'Nicholas';
Person.prototype.sayName = function () { 
    alert(this.name); 
}

let person1 = new Person();
let person2 = new Person();

person1.name = 'Greg';
alert(person1.name); // 'Greg'
alert(person2.name); // 'Nicholas'

delete person1.name;
alert(person1.name); // 'Nicholas

hasOwnProperty():若属性为实例属性,返回true:

person1.hasOwnProperty('name') // 如果person1实例本身有name属性,返回true

in操作符:无论该属性在实例中还是原型中,只要能通过对象访问,就返回true。

'name' in person1 // 检测person1是否有name属性,无论是实例还是原型属性

for-in: 返回的是所有能通过对象访问的、可枚举的属性,包括实例属性和原型属性。屏蔽了原型中不可枚举属性的实例属性也会被返回,因为按规定,开发人员定义的属性都是可枚举的(IE8及更早版本中例外)。

Object.keys():返回对象上所有可枚举的实例属性(IE 9+,Firefox 4+,Safari 5+,Opera 12+ 和 Chrome)。

Object.getOwnPropertyNames():返回对象上所有实例属性,包括不可枚举的(IE 9+,Firefox 4+,Safari 5+,Opera 12+ 和 Chrome)。

用new创建实例时经历的步骤

  1. 创建一个空的js对象,即{};
  2. 将该空对象[[Prototype]]属性链接到构造函数的原型对象 ;
  3. 将步骤1新创建的对象作为this的上下文 ;
  4. 执行构造函数内的代码(为这个新对象添加属性);
  5. 如果该函数没有返回对象,则返回this

用代码示意,记函数A为构造函数, new A() 实际做了如下事情:

let obj = {};
obj.__proto__ = A.prototype;
return A.call(obj) || obj;

1、new的过程中并不涉及constructor属性。改变A.prototype.constructor,也不影响new A()的执行过程:

function A () { console.log('A'); }
function B () { console.log('B'); }
B.prototype.constructor = A;
let b = new B(); // 'B'
console.log(b.__proto__ === B.prototype); // true
console.log(b.construtor === A); // true

2、new A也可以创建实例,和new A()的区别是new A不可以传入参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值