Javascript Object.defineProperty与构造函数和原型
我刚刚发现,而且我最熟悉C#我想在我的构造函数中使用访问器属性,例如:Javascript Object.defineProperty与构造函数和原型,javascript,properties,Javascript,Properties,我刚刚发现,而且我最熟悉C#我想在我的构造函数中使用访问器属性,例如: 函数库(id){ var _id=id; Object.defineProperty(这个“ID”{ get:function(){return\u id;}, 集合:函数(值){u id=value;} }) } 派生函数(id、名称){ var _name=名称; Base.call(这个,id); Object.defineProperty(此“名称”{ get:function(){return\u name;},
函数库(id){
var _id=id;
Object.defineProperty(这个“ID”{
get:function(){return\u id;},
集合:函数(值){u id=value;}
})
}
派生函数(id、名称){
var _name=名称;
Base.call(这个,id);
Object.defineProperty(此“名称”{
get:function(){return\u name;},
集合:函数(值){u name=value;}
})
}
Derived.prototype=Object.create(Base.prototype);
派生的构造函数=派生的;
var b=新基数(2);
var d=新衍生(4,“Alexander”);
控制台日志(b.ID);
console.log(d.ID,d.Name);
d、 ID=100;
console.log(d.ID,d.Name)代码>
有人能解释一下哪种方法适合我吗
不要使用Object.defineProperty
。这里绝对不需要属性描述符,而且getter和setter也不做任何特殊的事情。只需使用一个简单的法线属性。它将比您关心的任何其他东西都更快、更好地优化
function Base(id) {
this.ID = id;
}
function Derived(id, name) {
Base.call(this,id);
this.Name = name;
}
Derived.prototype = Object.create(Base.prototype);
Derived.prototype.constructor = Derived;
如果对于每个对象都重新生成函数,那么我可能需要考虑第二种方法:
是的,没错,但可以忽略不计。你不应该过早地进行微观优化。您将知道何时真正需要它,然后仍然可以轻松地交换实现。在此之前,请使用简洁明了的代码。我参加聚会可能会晚一点,但这里有几件小事我想指出
首先,您要在构造函数中定义自己的属性,这对于特定于实例的属性和不应与其他实例共享的属性很好,但对于getter、setter和方法则不行。相反,您应该在函数的原型上定义它们
我理解你这样的问题
你如何打造真正的私人房产?
它很简单,并且可以在所有浏览器中使用。首先,我们将详细介绍Object.defineProperty和派生的Object.create、Object.defineProperties
function MyConstructor() { /* example function or "class" */ }
javascript对象定义的原型
现代javascript允许一些“语法糖”来声明类,但是每一个自豪的开发者都应该理解它是如何工作的
首先没有课程。Javascript没有类。它有原型,而不是类。这些课程很像课堂,所以在我天真的固执中,我花了好几节课去寻找真相,我反对又反对——我一路走到底。没有课
让你
成为对象。如果您
或您的原型
无法回答问题,则会询问您的原型
,然后会询问您的原型
,直到没有更多原型可问
所有这些原型仍然是对象。该算法说明了这一点:
// Friendly version
function askQuestion(askee, question) {
do {
if (askee.hasOwnProperty(question)) {
return askee[question];
}
} while (askee = Object.getPrototypeOf(askee))
}
ECMAScript 6(无聊)
为了说明“现代javascript”的语法,我将离题:
class Tortoise extends Turtle {
constructor() {
while (this.__proto__) {
this.__proto__ = Object.getPrototypeOf(this.__proto__);
}
}
#privateProperty = "This isn't a comment"
get __proto__() { return Object.getPrototypeOf(this); }
set __proto__(to) { Object.setPrototypeOf(this, to); }
}
这并不适用于所有浏览器。它在任何浏览器中都不起作用。这只是为了显示语法
有人声称,上述内容只是老派javascript之上的语法糖,但当涉及到扩展本机对象时,它怀疑这其中有更多的东西
即使“现代javascript”(ECMAScript 6)允许我们编写如上所述的类,您也应该理解它
此外,现代javascript加上Internet Explorer 11的顽固性,迫使我们使用巴别塔(babel),这是一个非常棒的工具,具有难以置信的能力,非常先进、灵活,以至于这种工具存在的可能性,仅仅是巧合,是极不可能的
工具的存在本身就是上帝存在的证明,我很遗憾地说,这也证明了上帝不存在
WTF??见和,和
打开引擎盖
不要在构造函数中创建可重用属性。许多实例使用的函数不应在构造函数中赋值
真实版本
function Base(id) {
// GOOD
this.id = id;
// GOOD, because we need to create a NEW array for each
this.tags = [];
// Okay, but could also just be in the prototype
this.numberOfInteractions = 0;
// BAD
this.didInteract = function() {
this.numberOfInteractions++;
}
}
function Base(id) {
this.id = id;
this.tags = [];
}
Base.prototype.numberOfInteractions = 0;
Base.prototype.didInteract = function() {
this.numberOfInteractions++;
}
糖衣
class Base {
constructor(id) {
// GOOD
this.id = id;
// GOOD, because we need to create a NEW array for each
this.tags = [];
// Okay, but could also just be in the prototype
this.numberOfInteractions = 0;
// BAD
this.didInteract = function() {
this.numberOfInteractions++;
}
}
}
改进的真实版本
function Base(id) {
// GOOD
this.id = id;
// GOOD, because we need to create a NEW array for each
this.tags = [];
// Okay, but could also just be in the prototype
this.numberOfInteractions = 0;
// BAD
this.didInteract = function() {
this.numberOfInteractions++;
}
}
function Base(id) {
this.id = id;
this.tags = [];
}
Base.prototype.numberOfInteractions = 0;
Base.prototype.didInteract = function() {
this.numberOfInteractions++;
}
改良糖衣版
function Base(id) {
// GOOD
this.id = id;
// GOOD, because we need to create a NEW array for each
this.tags = [];
// Okay, but could also just be in the prototype
this.numberOfInteractions = 0;
// BAD
this.didInteract = function() {
this.numberOfInteractions++;
}
}
function Base(id) {
this.id = id;
this.tags = [];
}
Base.prototype.numberOfInteractions = 0;
Base.prototype.didInteract = function() {
this.numberOfInteractions++;
}
如果您坚持使用sugar,并且在编写代码之后喜欢编写更多的代码行和一些额外的工作,那么您可以安装babel并编写如下代码
它会使脚本文件稍微变大和变慢,除非你真的不需要支持所有的浏览器
class Base {
constructor(id) {
this.id = id;
this.tags = [];
}
numberOfInteractions = 0;
didInteract() {
this.numberOfInteractions++;
}
}
遗传ABC
EcmaScript中的继承非常简单,只要您真正理解它
TLDR:如果您希望上面的类扩展另一个类,您可以这样做:
Object.setPrototypeOf(Base.prototype, Parent.prototype);
这应该适用于所有地方。它本质上是Base.prototype.\uuuu proto\uuu=Parent.prototype
Base.prototype
vs实例prototype
var myInstance = new MyConstructor();
myInstance instanceof MyConstructor;
// this is TRUE because
Object.getPrototypeOf(myInstance) === MyInstance.prototype
javascript中的所有对象都有一个实例原型。它是为对象属性搜索“默认值”的实例原型
function MyConstructor() { /* example function or "class" */ }
上面的语句创建了一个名为MyConstructor
的对象,该对象有一个引用函数的实例原型。同时,它也是一个可以调用的函数
这很重要:
MyConstructor instanceof Function;
// is TRUE because
Object.getPrototypeOf(MyConstructor) === Function.prototype
// this is NOT TRUE
MyConstructor.prototype === Function.prototype
因为这种细微的差别
var myInstance = new MyConstructor();
myInstance instanceof MyConstructor;
// this is TRUE because
Object.getPrototypeOf(myInstance) === MyInstance.prototype
现在,MyConstructor.prototype
只是一个空对象(它有一个引用object.prototype
)的实例原型)
访问属性
在javascript中,对象只有属性。它们没有方法,但具有指向函数的属性
当您尝试访问上的属性时