Javascript 对象。创建原型链 初始问题
昨天我读了关于ECMAScript 5 Object.create()的文章 我想用这种方法在代码中构建原型链,而不是设置原型及其构造函数, 我喜欢你可以直接设置可写可配置等 我是这样试的Javascript 对象。创建原型链 初始问题,javascript,object,prototypal-inheritance,object-create,Javascript,Object,Prototypal Inheritance,Object Create,昨天我读了关于ECMAScript 5 Object.create()的文章 我想用这种方法在代码中构建原型链,而不是设置原型及其构造函数, 我喜欢你可以直接设置可写可配置等 我是这样试的 function printobject(msg, obj) { if (msg) { document.write("<b>" + msg + "</b><br>"); document.write("<hr><b
function printobject(msg, obj) {
if (msg) {
document.write("<b>" + msg + "</b><br>");
document.write("<hr><br>");
}
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (obj[prop].toString() !== "[object Object]") {
document.write(prop + " : " + obj[prop] + "<br>");
}
else {
document.write("<b>" + prop + " : " + obj[prop] + "</b><br>");
printobject("", obj[prop]);
}
}
}
if (msg) {
document.write("<br><hr><br>");
}
};
var base = {
extend: function () { //extend this Object
var args = Array.prototype.slice.call(arguments);
printobject("Arguments to Extend", args)
var that = Object.create(this, (args ? args.shift() : {}));
var arg = args.shift() || {};
printobject("Copy Properties to New Object", arg);
for (var prop in arg) {
that[prop] = arg[prop];
}
// Object.freeze(that);
return that;
},
create: function () { //Creates new instances of the Object
var that = Object.create(this, {
extend: {
value: null,
writable: false,
configurable: false
}, //sets extend and create to null so you cant create a new instance when used create ( use extend instead);
create: {
value: null,
writable: false,
configurable: false
}
});
that.init.apply(that, arguments); //call init function for the new created object;
return that;
},
init: function () {
printobject("No Initfunction supplied for New Object", this);
} // Empty init function for fallback
}
var Human = base.extend({
name: {
value: "test"
}
}, {
init: function (name) {
alert(name + " has been created");
this.name = name;
},
walk: function () {
alert(this.name + " walks");
}
});
var Human1 = Human.create("test2");
//alert("Human1 - Name:" + Human1.name);
Human1.walk();
Human.walk = function () {
alert("Walk has been overwritten")
}; //Object freezed
Human1.walk();
Human1.create = function () {
alert("Overwrite create");
}; //Doesnt exist in created Object
Human1.create(); ?
2:所以instanceof操作符在这段代码中没有中断,(它只对函数有效,这一点我似乎很清楚)
但是这样写的话,Paul仍然从Top的原型继承了inherit()方法
我需要覆盖它
但是如果我不想让Human的实例继承这个方法,我该怎么做呢
除了使用Objkect.defineproperty(?)之外,我无法设置像wrtable这样的属性描述符
那么,使用Object.create()从对象继承的主要好处是什么
设置原型和构造?=)
3:噢,thx,是的,这是定义对的,这不是基本对象的扩展=)
建议的thx=)
全力以赴的Thx=)
答复
好吧,那我什么时候去
Nothing={}
base.prototype=无
这不会阻止s.o沿着原型链上升,直到Object.prototype?
如果没有,是否有办法做到这一点?=)(Object.create(null);)会这样做吗
我想我必须要
base.prototype.constructor=base
否则,构造函数的原型
var Top=新的基()
如果原型设置为Nothing,则将为Nothings或Not base从原型链的某个位置继承构造函数->
基的顶级实例//false
更新
我现在就这样做了:
var base = {
// a tiny little selfmade prototypical inheritance system
// you are free to add function arguments for extending the created objects
// neither instanceof nor .constructor is featured, because "classes" are no functions
create: function(extension,desc) {
// instances inherit from the proto objects
var newInst = Object.create(this.proto, desc);
if(this.proto.childExtendable) //if Subclass allows its Children to be Extendible, do so
newInst.extend(extension);
if(newInst.init||this.proto.init) //4
newInst.init()
return newInst
},
inherit: function(props) {
// the "class" inherits static methods from the class
var sub = Object.create(this);
// and the proto objects inherits from the parent proto
sub.proto = Object.create(this.proto);
props.protect = this.protect;
if(props.childExtendable)
props.extend = this.extend;
this.extend.call(sub.proto, props);
return sub;
},
extend: function (props) {
for (var prop in props) {
var propmatch = prop.match(/(.*?)__(.{1,5}?)__(.*)/)||["",prop,"",""];
this[propmatch[1]+propmatch[3]] = props[prop];
if(propmatch[2])
this.protect(propmatch[1]+propmatch[3],propmatch[2]);
}
},
protect: function(prop,flags) { //with each call it toggles the given flags, so you can protect funcitons given to the inherit function ;; //This should be available to all childs, but adding it to the base.proto, it changes Object.prototyppe ( therefore not a good idea)
var d = Object.getOwnPropertyDescriptor(this, prop);
if (flags.match(/w/)){
Ti.API.info("Setting writable for propertie " + prop + " in Object " + this + " to " + !d.writable);
Object.defineProperty(this, prop, {writable:!d.writable});};
if (flags.match(/c/)){
Ti.API.info("Setting configurable for propertie " + prop + "in Object " + this);
Object.defineProperty(this, prop, {configurable:!d.configurable});};
if (flags.match(/e/)){
Ti.API.info("Setting enumerable for propertie " + prop + "in Object " + this);
Object.defineProperty(this, prop, {configurable:!d.enumerable});};
if (flags.match(/a/)){
Ti.API.info("Setting enumerable for propertie " + prop + "in Object " + this);
Object.preventExtensions(this);};
},
init: function() {},
proto: Object.prototype // or null, if you want
};
var Human = base.inherit({ //will be put in Human.proto
childExtendable:true,
init:function() {alert("Humans Init for all Instances")},
say:function() { alert("Hi, I'm "+this.name); }
});
Human.proto.name = "default"; // You could use an argument to the inherit function
// I just want to make clear what happens
Ti.API.info(Object.getPrototypeOf(Function) + "a");
var paul = Human.create({ //extends this object
name: "Paul",
test: function() {alert("test")},
init__wce__: function() {alert("Pauls Own Init")},
say__w__ : function() { alert("Hi, I'm" + this.name + "s Own Function")}
});
paul.name = "Paul"; // and again, the create function might do it for you
paul.say = function() {alert("Pauls say is overwritten")} // define init without __wce__ and it will be overwritten
paul.say(); // -> "Hi, I'm Paul"
只要有人在乎然而,JSFIDLE不会运行此功能,Tianium会按预期完成所有工作 也许是某种严格的模式(??) 人类给出的方法在ram中只存在一次吗 对 Human1.walk()指向它 对。更准确地说,
Human1
,Human1
的原型有一个指向它的属性“walk”
我想知道这样做是否正确?我对JavaScript比较陌生
我会说不,因为这太复杂了,而且部分是错的
- 人类实例的原型链包括
。这很奇怪,您需要覆盖每个实例的create和extend方法。通常的方法是“类”包含一个“原型”属性,它们的实例从中继承base
- 您的模式会破坏
操作符,尽管这可能是个小问题instanceof
- extend方法令人困惑。它不扩展对象本身,而是创建一个从中继承的新对象,并在该对象上设置属性和属性描述符。更好地实施同样的事情:
对延伸问题:
base.prototype = Nothing;
base.constructor = base;
这是毫无用处的。首先,任何函数的“prototype”属性在默认情况下都是(几乎)空对象,直到覆盖它为止。无需将其设置为无
:-)
“构造函数”属性通常是原型属性。它将被所有实例继承,指向i构造函数。您只需要在重写函数的“prototype”属性时显式地设置它,而不应该在函数本身上设置“constructor”属性
(继续:)我想了更多关于这样一个解决方案的信息:
var base = {
// a tiny little selfmade prototypical inheritance system
// you are free to add function arguments for extending the created objects
// neither instanceof nor .constructor is featured, because "classes" are no functions
create: function([desc]) {
// instances inherit from the proto objects
return Object.create(this.proto, [desc]);
},
inherit: function([props]) {
// the "class" inherits static methods from the class
var sub = Object.create(this);
// and the proto objects inherits from the parent proto
sub.proto = Object.create(this.proto);
[Object.extend(sub.proto, props);]
return sub;
},
proto: Object.prototype // or null, if you want
};
var Human = base.inherit();
Human.proto.name = "default"; // You could use an argument to the inherit function
// I just want to make clear what happens
Human.proto.say = function() { alert("Hi, I'm "+this.name); };
var paul = Human.create();
paul.name = "Paul"; // and again, the create function might do it for you
paul.say(); // -> "Hi, I'm Paul"
这样,paul
继承自Human.proto
继承自base.proto
,后者是Object.prototype
或null
。而Human
继承自base
,也就是说,您可以使用Human.inherit()
轻松构建一个“子类”
是否要使用属性描述符完全是您的选择。无论您在何处创建并扩展它,都可以使用对象.defineProperties
(或对象.create
)的第二个参数)以及对象.extend
(通常用于in-copy方法)
使用Object.create()从对象继承与设置原型和构造函数相比,有哪些主要好处
这是一种设计选择<代码>对象。创建不会对生成的对象调用[constructor]函数。有关更多信息,请参阅或
base.prototype={}代码>不阻止s.o在Object.prototype之前进入原型链
对。空对象(由文字创建)的链中仍然有对象.prototype
。唯一的方法是Object.create(null)
(不能使用new
)进行填充)
我认为我必须设置base.prototype.constructor=base代码>
在这种情况下没有。拥有函数base(){…}
,将其“prototype”属性设置为{constructor:base}
绝对不会改变任何东西(除了enumerable now中的“constructor”)——每个函数都有这样一个默认的proto对象,包括“constructor”
因此,只有当您需要用一个新对象覆盖“prototype”属性时,就像让它从另一个函数的原型继承时一样,您才可以添加这个方便的属性:MySubClass.prototype=object.create(MyClass.prototype,{constructor:{value:MySubClass})代码>
否则
什么也不会发生。原型对象上的“构造函数”属性不需要任何语言功能(如instanceof
),很少使用。很可能没有任何内容中断。您无法在注释中格式化代码。您应该删除它们,并通过编辑将代码添加到问题中。instanceof运算符仅适用于函数对象。用你的原始代码尝试Human1 instanceof Human
。Thnx=)编辑答案,是的,在原始代码中它不起作用=)我无论如何都不明白为什么它只适用于construcotr,在我看来是不对的好的,我已经回答了
base.prototype = Nothing;
base.constructor = base;
var base = {
// a tiny little selfmade prototypical inheritance system
// you are free to add function arguments for extending the created objects
// neither instanceof nor .constructor is featured, because "classes" are no functions
create: function([desc]) {
// instances inherit from the proto objects
return Object.create(this.proto, [desc]);
},
inherit: function([props]) {
// the "class" inherits static methods from the class
var sub = Object.create(this);
// and the proto objects inherits from the parent proto
sub.proto = Object.create(this.proto);
[Object.extend(sub.proto, props);]
return sub;
},
proto: Object.prototype // or null, if you want
};
var Human = base.inherit();
Human.proto.name = "default"; // You could use an argument to the inherit function
// I just want to make clear what happens
Human.proto.say = function() { alert("Hi, I'm "+this.name); };
var paul = Human.create();
paul.name = "Paul"; // and again, the create function might do it for you
paul.say(); // -> "Hi, I'm Paul"