Javascript 基础篇七:原型

原型

一、对象属性

对象引用属性:当引用一个对象的属性时,触发默认的 [[Get]] 操作,先检查对象本身是否存在这个属性,有则使用,无则继续访问对象的 [[prototype]] 链。

所有普通的 [[prototype]] 链最终都会指向内置的 Object.prototype。

对象属性设置:

  1. = 操作符
    如果设置的属性既出现在对象本身,也出现在 [[prototype]] 链上层,会发生隐蔽。
    对象包含的该属性会屏蔽原型链上层的所有该属性。因为对象属性的设置会选择原型链最底层的该属性。

    如果设置的属性不存在于该对象而是存在于原型链上层时:
    1、该属性是普通数据访问属性且 writable: true 直接在该引用对象中添加该属性,屏蔽属性。
    2、该属性是普通数据访问属性且 writable: false 则该赋值语句被忽略;严格模式下报错,不发生屏蔽。
    3、该属性是一个 setter,那就一定会调用这个 setter。不会添加到引用对象上,也不会重新定义 setter,不发生屏蔽。

  2. 使用 Object.defineProperty(…)
    不会受到屏蔽情况影响。

二、“类”函数

所有的函数默认都会拥有一个名为 prototype 的共有且不可枚举的属性,它会指向另一个对象。

javsscript 会在两个对象之前创建一个关联,这样一个对象就可以通过委托访问另一个对象的属性和函数。

函数不是构造函数。当且仅当使用 new 时,函数调用会变成“构造函数调用”。
new Fun() 间接完成了目的:一个关联到其他对象的新对象。

Fun.prototype 默认有一个公有且不可枚举的属性 .constructor。这个属性引用的是对象关联的函数(Fun)。

.constructor 是可变属性,但不可枚举。它的值是可写的,你可以给任意 [[prototype]] 链中的任意对象添加一个名为 constructor 的属性或对其进行修改。可以任意对其赋值。

function Fun(name) {
	this.name = name;
}

Fun.prototype.constructor === Fun;	//true
Fun.prototype.myName = function() {
	return this.name;
}

var a = new Fun("a");
a.constructor === Fun;	//true
a.myName();	//"a"

面向类技巧

  1. this.name = name 给每个对象(a)都添加了 .name 属性。有点像类实例封装的数据值。
  2. Fun.prototype.myName = … 给 Fun.prototype 对象添加了个属性函数。而 a 的内部 [[prototype]] 关联到 Fun.prototype。
    所以调用时在 a 无法找到会在 Fun.prototype 上找。
  3. a.constructor 引用同样委托给了 Fun.prototype。

三、(原型)继承

关联方法

  1. Fun2.prototype = Object.create(Fun1.prototype);
    创建一个新的 Fun2.prototype 对象并把它关联到 Fun1.prototype;旧对象被抛弃,不能直接修改已有默认对象。
  2. Fun2.prototype = Fun1.prototype;
    直接引用 Fun1.prototype 对象,对新对象赋值会直接修改 Fun1.prototype 对象本身。
  3. Fun2.prototype = new Fun1();
    构造函数调用,小副作用,影响后代,尽量不用。
  4. Object.setPrototypeOf(Fun2.prototype, Fun1.prototype);
    标准可靠的方法(ES6)

检查“类”关系

  1. instanceof:只能处理对象和函数。
    注意:构造函数中使用 .bind() 相当于直接调用目标函数,在硬绑定函数上使用 instanceof 相当于直接在目标函数上使用 instanceof。
  2. isPrototypeOf(…):处理对象和对象。
  3. Object.getPrototypeOf(…) = .__ proto __ :引用内部 [[prototype]] 对象来判断。
//使用
a instanceof Fun;
Fun.prototype.isPrototypeOf(a);
b.isPrototypeOf(a);
Object.getPrototypeOf(a) === a.__proto__ === Fun.prototype

其中 .__ proto __ 像属性,但更像 getter。

Object.defineProperty(Object.prototype, "__proto__", {
	get: function() {
		return Object.getPrototypeOf(this);
	},
	set: function() {
		Object.setPrototypeOf(this, o);
		return o;
	}
})

四、对象关联

Object.create()

ES5之前版本 ployfill
if(!Object.create) {
	Object.create = function() {
		function F() {};
		F.prototype = o;
		return new F();
	}
}

Object.create(null) 会创建一个拥有空 [[prototype]] 链接的对象。这个对象无法进行委托。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值