JavaScript 的原型对象

JavaScript 的原型对象

当我们使用构造函数创建实例对象时,每创建一个对象,对象中的属性和方法都会创建一份。当对象很多时,就会消耗大量的内存,影响网页的性能。其实,实例对象中有的属性和方法是相同的,我们能不能只创建一份就行了呢?当然,我们可能就会想到在全局作用域中声明变量和函数来保存对象的属性和方法了。但是,全局作用域不安全(对象中的属性和方法容易被访问或修改)和容易受到污染。这时候,我们可能就需要一个只能被同一个类创建的实例对象才能够访问到的公共空间了。

原型对象的定义

每当我们创建一个函数时,浏览器解析器都会向函数中添加一个属性 prototype,这个属性指向一个对象,这个对象就是原型对象。

  • 当这个函数是一个普通函数时,属性 prototype 没有任何作用;
  • 当这个函数是一个构造函数时,这个构造函数所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,可以通过__proto__来访问该属性。
function MyClass(){
}
console.log(MyClass.prototype);		//函数的 prototype 属性
var mc = new MyClass();
console.log(mc.__proto__);		//对象的 __proto__ 属性

上面代码会输出两个 Object 对象,都指这个构造函数的原型对象。

  • 利用构造函数创建的所有对象的__proto__属性指向的原型对象和这个构造函数的 prototype 属性指向的原型对象是同一个对象,所以他们是相等的。
function MyClass(){
}
var mc1 = new MyClass();
var mc2 = new MyClass();
console.log(MyClass.prototype == mc1.__proto__);	// true
console.log(mc1.__proto__ == mc2.__proto__);		// true

原型对象的作用

原型对象相当于一个公共区域,所有同一个类的实例都可以访问到该类的原型对象。可以将实例中的共有的内容,统一设置在原型对象中,以供所有实例访问。
语法1:构造函数名.prototype.属性名 = 属性值;
语法2:构造函数创建的实例.__proto__.属性名 = 属性值;

//往 MyClass 的原型对象中添加属性 name
MyClass.prototype.name = "lin";
//访问实例的原型对象的属性 name
console.log(mc1.name);		//输出 lin

原型对象的使用规则

  1. 当访问对象的一个属性或方法时,首先会在该对象自身中寻找,如果存在,直接使用;如果不存在,则去原型对象中寻找。
MyClass.prototype.name = "lin";
mc1.name = "haha";
//访问实例的原型对象的属性
console.log(mc1.name);

mc1 中的存在 name 属性,直接访问自身的属性 name。不再去原型对象中寻找。

  1. 使用 in 运算符检查对象中是否含有某属性时,如果对象自身中没有,但是原型对象中有,也会返回 true。
  2. 使用对象的 hasOwnProperty() 方法来检查对象是否含有某属性,如果对象自身中没有,就算原型对象中有,也会返回 false。
  3. 对象的原型对象也是一个对象,它也有原型对象。所以,上面第1条规则应该改为:当访问对象的一个属性或方法时,首先会在(1)该对象自身中寻找,如果存在,直接使用,不再寻找;如果不存在,则去(2)原型对象中寻找,如果原型对象存在,直接使用,不再寻找;如果原型对象不存在,则去(3)原型对象的原型对象中寻找,以此类推,直到找到(4) Object 对象的原型。Object 对象的原型没有原型对象了,所以如果在 Object 对象的原型中仍然没有找到,则返回 undefined 。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值