JavaScript 面向对象(一)

1、无论什么时候,只要创建了一个函数,就会默认给这个函数创建一个prototype属性,这个属性指向这个函数的原型对象。所有原型对象都会自动获得一个constructor属性,这个属性包含一个指向prototype属性所在的函数的指针。

function Person(){
    name: 'Bob',
    sayName: function(){
        console.log(this.name)
    }
}

var person1 = new Person()
Person.prototype == person1.__proto__;//true

2、通过构造函数创建的实例,都会有一个__proto__属性,这个属性是指向该构造函数的prototype属性所在的原型对象的一个指针。也就是说,实例和构造函数之间其实是没有什么关联的

这里写图片描述

3、当为实例添加一个属性的时候,该属性默认会覆盖原型中的同名属性,不过可以通过delete操作符删除实例中的属性,然后就可以再次访问到原型中的同名属性了。

function Person(){
    name: 'Bob',
    sayName: function(){
        console.log(this.name)
    }
}

var person1 = new Person();
person1.name = "Linda";
console.log(person1.name);//"Linda"
//使用delete删除实例中的同名属性
delete person1.name;
person1.name;//"Bob"

4、几个常用的操作符和方法
(1) hasOwnProperty()
当要校验的属性存在于对象实例中,而不是原型中时,该方法返回true
(2)for-in
使用for-in循环,返回的是能够通过对象访问的,可枚举的所有属性,无论该属性存在于原型中还是实例中。当重写了原型中不可枚举的属性时,重写后的属性,也会出现在for-in循环中。
(3)in
该操作符会在属性可以通过”对象.属性”的方式访问到给定属性的时候返回true,无论该属性存在于实例中还是原型中
(4)Object.keys()
该方法返回对象上所有可枚举的实例属性组成的字符串数组。
(5)Object.getOwnPropertyNames()
该方法返回所有实例属性,不管该属性是否可枚举。

5、调用构造函数创建实例时,会为实例创建一个指向最初原型的__proto__指针,但是重写原型(使用对象字面量的方式),会切断构造函数与最初原型之间的联系。而且会导致原型中的constructor属性不再指向原来的构造函数,而是指向Object。

这里写图片描述

  • 使用对象字面量的方式,实际上相当于重写了对象的原型,而一开始创建的person1实例,__proto__属性指向的还是最初的原型对象,而不是重写后的原型对象,所以会报错。
  • 重写原型,切断了现有原型与重写之前创建的所有实例之间的联系,他们引用的还是最初的原型

可以使用下面的方式,将原型中的constructor属性重新指向Person构造函数,但是这种方式会导致constructor属性的[[Enumerable]]特性设置为true(默认为false)。

Person.prototype = {
    constructor: Person,
    name: "bob",
    sayName: function(){
        console.log(this.name)
    }
}

可以使用Object.defineProperty()方法,将constructor属性的可枚举属性,设置为false。

Object.defineProperty(Person.prototype,"constructor",{
    enumerable: false,
    value: Person
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值