ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

对象原型

2021-09-10 11:02:17  阅读:130  来源: 互联网

标签:prototype Bar 对象 Object 原型 obj Foo true


前言

嘿,骚年,你是否还在使用JavaScript的"伪"类应付了事,而没有使用更简洁的"行为委托"设计模式?你是否听说连接到其他对象的对象?
如果都没有,那就接着往下看吧。

属性描述符

首先来了解一点准备知识,什么是属性描述符呢?即writable(可写)、enumerable(可枚举)、configurable(可配置)。我们可以使用Object.defineProperty()来添加一个新属性或者修改一个已有属性(configurable为true)并对特性进行设置

writable

writable决定是否可以修改属性的值

var obj = {}
Object.defineProperty( obj, 'a', {
  value: 2,
  writable: false, //不可写
  configurable: true,
  enumerable: true
})
obj.a = 3;
console.log(obj.a); //2

如上,修改a失败,因为我们配置了writable:false。如果在严格模式下,会直接报错。

configurable

configurable决定属性是否可以被配置

var obj = {
  a: 2
}
obj.a = 3;
console.log(obj.a); //3
Object.defineProperty( obj, 'a', {
  value: 4,
  writable: true,
  configurable: false, //不可配置
  enumerable: true
});
console.log(obj.a) //4
obj.a = 5;
console.log(obj.a) //5
Object.defineProperty( obj, 'a', {
  value: 4,
  writable: true,
  configurable: true, //不可配置
  enumerable: true
}); //TypeError

不管是否处于严格模式,尝试修改一个不可配置的属性描述符都会出错;除了无法修改,configurable还会禁止删除这个属性。

enumerable

控制属性是否会出现在对象的属性枚举中

var obj = {
  a: 1
}
Object.`defineProperty`( obj, 'b', {
  value: 2,
  writable: true,
  configurable: true,
  enumerable: true
});
Object.`defineProperty`( obj, 'c', {
  value: 3,
  writable: true,
  configurable: true,
  enumerable: false
})
for(let i in obj) {
  console.log(obj[i])
} // 1, 2

如上,c无法被枚举到

原型

JavaScript中的对象都有一个[[Prototype]]内置属性,其实就算对于其他对象的引用。思考下面代码:

function Foo(name) {
  this.name = name
}
function Bar(name, label) {
  Foo.call(this, name)
  this.label = label
}
Bar.prototype = Object.create( Foo.prototype )
console.log(Bar instanceOf Foo) //true

这段代码的核心部分就算语句Bar.prototype = Object.create( Foo.prototype )。调用Object.create()会凭空创建一个"新"对象并把新对象内部的[[Prototype]]关联到指定的对象(Foo.prototype).即创建一个新的Bar.prototype对象并把它关联到Foo.prototype。

行为委托

首先看看面向类和面向委托的理论设计:

类理论

如果使用类,通常会创建一个父类,然后子类继承父类,且类鼓励你去重写它的方法。
下面是伪代码

class Task {
  id;
  //构造函数Task()
  Task(ID) {id = ID;}
  outputTask() { output(id); }
}

class XYZ inherits Task {
  label;
  //构造函数XYZ()
  XYZ(ID, Label) { super(ID); label = label; }
  outputTask() { super(); output( label );}
}

class ABC inherits Task { .... }

现在你需要实例化子类XYZ的一些副本然后使用实例来执行"XYZ"。这些实例有Task定义的公共部分和XYZ定义的特殊行为。同理ABC也一样。

委托理论

首先需要定义一个Task对象,它会有所有任务都能使用的具体方法,然后对于每个任务('XYZ','ABC')你都需要定义一个对象来存储对应的数据和自己特殊行为。然后将这些具体任务对象关联带Task对象上,让它们在需要的时候可以进行委托。

Task = {
  setID: function(ID) { this.id = ID; }
  outputID: function() { console.log(this.id); }
};
//让XYZ委托Task
XYZ = Object.create(Task)
XYZ.prepareTask = function( ID, Label ) {
  this.setID( ID );
  this.label = label;
}
//ABC....

可以看出来代码更加简洁并且更加容易懂了吧(桃某人觉得是这样hhhh)

比较思维模型

思维模型要画图,太恼火了,我就直接上代码了,参考《你不知道的JavaScript》(上卷170页)

//面向对象风格
function Foo(who) {
  this.me = who;
} 
Foo.prototype.identify = function() {
  return "I am " + this.me;
}

function Bar(who) {
  Foo.call(this, who)
}
Bar.prototype = Object.create( Foo.prototype );

Bar.prototype.speak = function() {
  alert( "Hello," + this.identify() + "." );
};

var b1 = new Bar( "b1" );
var b2 = new Bar( "b2" );

b1.spreak();
b2.spreak();

子类Bar继承父类Foo,然后生成了b1和b2两个实例。b1委托Bar.prototype,Bar.prototype委托Foo.prototype。

//对象关联风格
Foo = {
  init: function(who) {
    this.me = who;
  },
  identify: function() {
    return " I am " + this.me;
  }
};
Bar = Object.create( Foo );

Bar.speak = function() {
  alert("Hello, " + this.identify() + '.');
};

var b1 = Object.create( Bar )
var b2 = Object.create( Bar )
b1.init( 'b1' )
b2.init( 'b2' )
b1.speak()
b2.speak()

这段代码中我们利用[[prototype]]把b1委托给Bar,并把Bar委托给Foo,与上面的一模一样。但是代码简洁了很多,因为我们只是将对象关联起来了,并不需要模仿类的行为。

标签:prototype,Bar,对象,Object,原型,obj,Foo,true
来源: https://www.cnblogs.com/taosifan/p/15248812.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有