JavaScript动态特性的副作用

60 篇文章 0 订阅
55 篇文章 1 订阅

JavaScript是一门动态语言,可以很容易地添加、删除和修改属性。这种特性同样适合于原型,包括函数原型和对象原型。

console.log("---------------通过原型,一切都可以在运行时修改------------");
//定义了一个构造函数,该构造函数中创建了一个swung属性,初始化为布尔值
function NinjaTest3() {
  this.swung = true;
}

//通过new操作符调用构造函数,创建实例NinjaTest3
const ninjaTest3 = new NinjaTest3();

//在实例对象创建完成之后,在原型上添加一个方法
NinjaTest3.prototype.swingSword = function () {
  return this.swung;
}

//验证该方法存在于对象中
if (ninjaTest3.swingSword()) {
  console.log("Method exists, even out of order");
}

//使用字面量对象完全重写NinjaTest3的原型对象,仅有一个pierce方法
NinjaTest3.prototype = {
  pierce: function () {
    return true;
  }
}

//尽管我们已经完全替换了NinjaTest3的构造器原型,但是实例化后的NinjaTest3对象仍然具有swingSword方法,因为对象ninjaTest3仍然保持着对旧的NinjaTest3原型的引用
if (ninjaTest3.swingSword()) {
  console.log("Our ninja can still swing!");
}

const ninjaTest3_2 = new NinjaTest3();
if (ninjaTest3_2.pierce()) {
  console.log("Newly created ninjas can pierce.");
}
if (!ninjaTest3_2.swingSword) {
  console.log("ninjaTest3_2.swingSword:" + ninjaTest3_2.swingSword);
  console.log("But they can not swing!");
}

从上面的代码发现:

定义了NinjaTest3构造器,并使用它创建一个对象实例。此程序的状态如下:

 

由上图可知:构造完成之后,ninjaTest3 具有swung属性,它的原型是NinjaTest3原型,仅有一个构造属性。

 

实例对象创建完成之后,我们在原型上添加swingSword方法。通过执行测试来验证可以在对象创建完成之后,修改对象的原型。如下如所示:

 

 

 

 

 

因为ninjaTest3实例指向NinjaTest3原型,在实例构造完成之后对原型作更改,该实例仍然能够访问。

然后我们使用字面量对象完成重写NinjaTest3的原型对象,该字面量对象仅含有pierce方法。如下图:

 

 

函数的原型可以被任意替换,已经构建的实例引用旧的原型。从上图可以发现:即使NinjaTest3 函数不再指向旧的NinjaTest3 原型,但是旧的原型仍然存在于ninjaTest3 实例中,通过原型链依然可以访问到swingSword方法。

但是,此时在NinjaTest3 发生变化之后再创建新的实例对象,此时应用程序的状态如下:

 

 

新创建的实例引用新的原型

对象与函数原型之间的引用关系是在对象创建时建立的。新创建的对象将引用新的原型,它只能访问piercr方法,原来旧的对象保持着原有的原型,仍然能够访问swingSword方法。

 

 

参考《JavaScript忍者秘籍》

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值