javascript – Object.create原型链
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – Object.create原型链,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10178字,纯文字阅读大概需要15分钟。
内容图文
![javascript – Object.create原型链](/upload/InfoBanner/zyjiaocheng/792/a3d38d6807ed4c42a727fe089caefe6d.jpg)
初步问题
昨天我读到了ECMAScript 5 Object.create()
我想用这种方法开始在我的代码中构建原型链,而不是设置原型及其构造函数,
我喜欢你可以直接设置可写配置等.
我试过这样的
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(); ?
> Human中给出的方法只在ram中存在一次吗?和Human1.walk()指向它?
>我想知道这是否是这样做的正确方法?我是JavaScript的新手.
这是jsfiddle上的代码.
回答
首先,很多事情让事情变得清晰=)
但,
1:当我这样做时,实例继承自构造函数的原型(?)
Nothing = {};
function base() {
this.inherit = function(constructor) {
alert("inherit");
var obj = constructor;
obj.constructor = constructor;
obj.prototype = this;
return obj ;
}
;}
base.prototype = Nothing;
base.constructor = base;
var Top = new base();
var Human = Top.inherit(function(name) {
this.name = name;
});
var Paul = new Human("Paul");
alert(Paul.name);
alert(Paul instanceof Human); //true `
2:所以instanceof运算符不会破坏这个代码,(它对函数起作用只对我来说很明显)
但是这样编写,Paul仍然从Top的原型继承了inherit()方法
我需要覆盖它
但是,如果我不希望Human的实例继承该方法,我该怎么做?
除了使用Objkect.defineproperty(?)之外,我无法设置像wrtable这样的属性描述符
那么使用Object.create()从Objects vs继承的主要好处是什么呢?
设置原型和构造器? =)
3:哦thx,是的,那就是defs那不是基础对象的扩展=)
thx的建议=)
感谢所有的努力=)
回答
好吧,当我这样做
Nothing = {}
base.prototype = Nothing;
这不会阻止s.o上升到原型链直到Object.prototype?
如果没有,有没有办法做到这一点? =)会(Object.create(null);)这样做,
我以为我必须设置
base.prototype.constructor = base;
因为否则,原型的构造函数
var Top = new base();
如果原型被设置为Nothing,则Nothings’或者不会从原型链的某个地方继承构造函数 – >
Top instanceof 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"
只要有人关心
但是,jsfiddle将无法运行此功能,Titanium会按预期执行每个操作
也许一些严格的模式(??)
解决方法:
Do the methods given in Human only exist once in the ram?
是.
and Human1.walk() points to it?
是.更确切地说,Human1,Human的原型具有指向它的属性“walk”.
I wonder if this is the right Approach of doing it like this? I’m relatively new to JavaScript.
我会说不,因为它过于复杂,而且有些错误.
> Human实例的原型链包括base.多数民众多,你需要为每个实例覆盖create和extend方法.通常的方法是“类”包含一个“prototype”属性,它们的实例从中继承.
>您的模式会破坏instanceof运算符,尽管这可能是一个小问题.
>扩展方法令人困惑.它不会扩展对象本身,而是创建一个从它继承的新对象,并在其上设置属性和属性描述符.更好地实现同样的事情:
base.inherit = function(descs, props) {
// creates a new object inheriting from this
var that = Object.create(this, descs); // will even work when undefined
if (props)
for (var prop in props)
that[prop] = props[prop];
// Object.freeze(that);
return that;
};
对于扩展的问题:
base.prototype = Nothing?;
base.constructor = base;
没用了.首先,默认情况下,任何函数的“prototype”属性都是(几乎)空对象,直到您覆盖它为止.无需将其设置为空:-)
而“构造函数”属性通常是一个原型属性.它将由所有实例继承,指向thei构造函数.您只需要在覆盖函数的“prototype”属性时显式设置它 – 并且您不应该在函数本身上设置“构造函数”属性.
(继续:)我虽然更多关于这样的解决方案:
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()轻松构建“子类”.
您是否想要使用属性描述符绝对是您的选择.你可以在任何地方创建并扩展它,也可以使用Object.defineProperties(或Object.create的第二个参数)以及Object.extend(通常的for-in-copy-method).
what are the main benefits from using Object.create() to inherit from Objects vs Setting the prototypes and construcotrs?
这是一个设计选择. Object.create不会在构建对象上调用[constructor]函数.有关详细信息,请参见Using “Object.create” instead of “new”或Understanding the difference between Object.create() and new SomeFunction().
base.prototype = {};
doesnt prevent s.o to go up the prototype chain til Object.prototype?
是.一个空对象(由你的文字创建)在其链中仍然有Object.prototype.执行此操作的唯一方法是Object.create(null)(不能使用new进行填充).
i thought that i had to set
base.prototype.constructor = base;
不是在这种情况下.有一个函数base(){…},将它的“prototype”属性设置为{constructor:base}绝对没有任何变化(除了现在可枚举的“构造函数”) – 每个函数都有这样一个默认的proto对象,包括“构造函数” ”.
因此,只有当你需要用一个新对象覆盖“prototype”属性时,就像它让它从另一个函数的原型继承一??样,你可以添加这个便利属性:MySubClass.prototype = Object.create(MyClass.prototype,{constructor :{值:MySubClass}});
otherwise…
什么都不会发生.没有语言特征(如instanceof)需要原型对象上的“构造函数”属性,并且很少使用.没有什么能打破.
内容总结
以上是互联网集市为您收集整理的javascript – Object.create原型链全部内容,希望文章能够帮你解决javascript – Object.create原型链所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。