newJavaScript中的关键字在第一次遇到时会非常混乱,因为人们倾向于认为JavaScript不是面向对象的编程语言.
我最近Object.create()在JavaScript中偶然发现了这个方法,并试图推断它与创建一个对象的新实例有什么不同new SomeFunction(),当你想要使用另一个时.
请考虑以下示例:
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2Run Code Online (Sandbox Code Playgroud)
请注意,在两种情况下都观察到相同的行为.在我看来,这两种情况之间的主要区别是:
Object.create()实际使用的对象实际上形成了新对象的原型,而在new …我试图在javascript中实现继承.我想出了以下最小代码来支持它.
function Base(){
this.call = function(handler, args){
handler.call(this, args);
}
}
Base.extend = function(child, parent){
parent.apply(child);
child.base = new parent;
child.base.child = child;
}
Run Code Online (Sandbox Code Playgroud)
专家,请告诉我这是否足够或我可能错过的任何其他重要问题.根据面临的类似问题,请提出其他更改建议.
这是完整的测试脚本:
function Base(){
this.call = function(handler, args){
handler.call(this, args);
}
this.superalert = function(){
alert('tst');
}
}
Base.extend = function(child, parent){
parent.apply(child);
child.base = new parent;
child.base.child = child;
}
function Child(){
Base.extend(this, Base);
this.width = 20;
this.height = 15;
this.a = ['s',''];
this.alert = function(){
alert(this.a.length);
alert(this.height);
}
}
function Child1(){
Base.extend(this, Child);
this.depth = …Run Code Online (Sandbox Code Playgroud) 我正在创建一个Object在JavaScript 中扩展的类,并期望super()在构造此类的新实例时初始化键/值.
class ExtObject extends Object {
constructor(...args) {
super(...args);
}
}
const obj = new Object({foo:'bar'});
console.log(obj); // { foo: 'bar' }
const ext = new ExtObject({foo:'bar'});
console.log(ext); // ExtObject {}
console.log(ext.foo); // undefinedRun Code Online (Sandbox Code Playgroud)
为什么在此示例中foo未定义为'bar'on ext?
编辑
我一直在构建一个小型JS框架供我工作使用,我想使用Douglas Crockford的原型继承模式.我想我对原型对象的工作原理有了一般的了解,但不清楚的是我将使用这种模式的方式超出了最简单的例子.
我会把它充实到我明白的地步.
(function () {
'use strict';
var Vehicles = {};
Vehicles.Vehicle = function () {
this.go = function () {
//go forwards
};
this.stop = function () {
//stop
};
};
Vehicles.Airplane = Object.create(Vehicles.Vehicle());
}());
Run Code Online (Sandbox Code Playgroud)
所以现在我的Vehicles.Airplane对象可以去()和停止(),但我想要更多.我想将takeOff()和land()方法添加到此对象.之后我可以使用丑陋的点符号:
Vehicles.Airplane.takeOff = function () {
//take off stuff
}
Run Code Online (Sandbox Code Playgroud)
但这似乎是错误的,特别是如果我要添加许多方法或属性.这里提出的问题似乎与我的非常相似,但答案对我来说并不完全正确.答案表明我应该在使用Object.create之前构建一个对象文字,并且我应该将该对象文字传递给create方法.但是,在给出的示例代码中,看起来它们的新对象现在根本没有继承.
我希望的是一些语法类似于:
Vehicles.Airplane = Object.create(Vehicles.Vehicle({
this.takeOff = function () {
//takeOff stuff
};
this.land = function () {
//land stuff
};
}));
Run Code Online (Sandbox Code Playgroud)
我知道这个语法现在会用Object.create打破,因为我当然要传递Vehicle.Vehicle一个函数而不是一个对象文字.这不是重点.我想知道我应该以什么方式将一个新属性构建到一个继承自另一个的对象中,而不必在事后用点符号一次列出一个.
编辑:
Bergi在经历了一些关于这个话题的痛苦思考后,我想我真的想要用你所描述的"古典模式".这是我的第一次尝试(现在使用实际的代码片段,而不是模拟假设 - 你甚至可以看到我糟糕的方法存根):
CS.Button = function (o) …Run Code Online (Sandbox Code Playgroud) 我遇到过Douglas Crockfords Object.create方法的特殊性,我希望有人可以解释一下:
如果我创建一个对象 - 比如'person' - 使用对象文字符号,那么使用Object.create创建一个新对象 - 比如'anotherPerson' - 它继承了初始'person'对象的方法和属性.
如果我然后更改第二个对象的名称值 - 'anotherPerson' - 它还会更改初始'person'对象的名称值.
这只发生在嵌套属性时,这段代码应该让你知道我的意思:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
};
// initiate new 'person' object
var person = {
name: {
first: 'Ricky',
last: 'Gervais'
},
talk: function() {
console.log('my name is ' + this.name.first + ' ' + this.name.last);
}
}
// create anotherPerson from person.prototype
var anotherPerson = …Run Code Online (Sandbox Code Playgroud) 与此问题类似但不同.以下代码来自JavaScript:The Definitive Guide.他基本上定义了一个继承方法,如果它存在则遵循Object.create,否则使用构造函数和交换原型进行普通的旧Javascript继承.
我的问题是,由于Object.create在很多常见的 IE 浏览器中都不存在,甚至试图使用它有什么意义呢?它肯定会使代码混乱,上一个问题的一位评论者提到Object.create 并不是太快.
那么尝试添加额外代码以便偶尔使用这个ECMA 5函数有什么优势呢?这个函数可能会或者可能不会比这种"旧"方式慢?
function inherit(p) {
if (Object.create) // If Object.create() is defined...
return Object.create(p); // then just use it.
function f() {}; // Define a dummy constructor function.
f.prototype = p; // Set its prototype property to p.
return new f(); // Use f() to create an "heir" of p.
}
Run Code Online (Sandbox Code Playgroud) 这篇关于Object.create()JavaScript中的方法的答案谈到了差异继承.它接着说:
此方法允许您轻松实现差异继承,其中对象可以直接从其他对象继承.
据我所知,JavaScript总是允许对象通过原型继承直接从其他对象继承.JavaScript中没有类的概念.那么差异继承真正意味着什么呢?为什么这样称呼呢?
PS:我在一段时间后对该答案发表了评论,但我没有收到任何回复.所以想要与更大,更棒的SO JavaScript用户社区进行核实.
我想在EcmaScript 5 JavaScript中为类添加静态函数.我的类定义如下:
var Account = {};
Object.defineProperty(Account, 'id', {
value : null
});
Run Code Online (Sandbox Code Playgroud)
我会创建一个这样的新实例:
var theAccount = Object.create(Account);
theAccount.id = 123456;
Run Code Online (Sandbox Code Playgroud)
现在我想在Account类中添加一个静态函数.如果我Account使用构造函数和prototype类似的属性创建了类:
var Account = function () {
this.id = null;
};
Run Code Online (Sandbox Code Playgroud)
......我可以这样做:
Account.instances = {};
Account.createInstance = function () {
var account = new Account();
account.id = uuid.v4();
Account.instances[account.id] = account;
return account;
};
Run Code Online (Sandbox Code Playgroud)
但是因为我正在使用Object.defineProperty而不是prototype添加成员的属性,Account.instances并且Account.createInstance在调用时也会被实例化Object.create,因此是实例的属性.
在使用EcmaScript 5样式对象创建时,如何向类中添加静态成员?
javascript ×10
inheritance ×3
ecmascript-5 ×2
prototype ×2
bind ×1
ecmascript-6 ×1
function ×1
new-operator ×1
object ×1