可重用javascript对象、原型和范围
长名函数必须可以从可重用javascript对象、原型和范围,javascript,scope,prototype,Javascript,Scope,Prototype,长名函数必须可以从MyGlobalObject调用,而在加载脚本后,该函数必须始终作为全局(to窗口)变量可用。它应该支持符合最新标准的扩展性 对于如何为应用程序(几乎100%的JS)构建JS库,我处于一个体系结构的两难境地 我们需要一个对象,即window.MyObject(像一个模块,像jQuery),所以 它可以用 VAR1 MyGlobalObject; function TheFunctionICanUseRightAwaySingleForAllInstansesAndWithou
MyGlobalObject
调用,而在加载脚本后,该函数必须始终作为全局(to窗口
)变量可用。它应该支持符合最新标准的扩展性
对于如何为应用程序(几乎100%的JS)构建JS库,我处于一个体系结构的两难境地
我们需要一个对象,即window.MyObject
(像一个模块,像jQuery),所以
它可以用
VAR1
MyGlobalObject;
function TheFunctionICanUseRightAwaySingleForAllInstansesAndWithoutInstanse() {
function() {
alert('NO CONSTRUCTOR WAS CALLED');
}
};
MyGlobalObj
可扩展吗?我是否可以创建子对象,该子对象将继承当前状态的MyGlobalObj
(扩展函数/属性MyGlobalObj.NewFunc
e.g.)?使用原型(VAR3)的主要区别是什么
我所说的GlobaldFunction
是指所有初始化/实例化(可能可实例化)实例的单个实例
或与
VAR2
var MyGlobalObjConstructor = function(){
this.GlobalFunctionInObject = function(){
alert('called with MyGlobalObj.GlobalFunctionInObject()');
}
};
window.MyGlobalObj = new MyGlobalObjConstructor();
或与
VAR3
var MyGlobalObj = {
GlobalFunctionInObject: function...
GlobalFunctionInObject2: function...
};
MyGlobalObj.GlobalFunctionInObject();
// here I lose all hierarchy elements, no prototype,
// can I use GlobalFunctionInObject2 in GlobalFunctionInObject?
将MyGlobalObj定义为函数和对象(func或VAR2的结果)有什么区别
或VAR4?
我在Chrome调试器中看到prototype和\uuuuu proto\uuuu
特殊字段。我已经读过了,没关系,但是为什么它们不保存在一个原型中呢
那么,实现
window.MyObject
的正确/最佳方法是什么,这样就可以MyObject.MyFunction()代码>变量1、2和3的区别(正反)是什么?我通常通过返回一个具有函数作为属性的对象来解决:
var MyGlobalConstuctor = function(){} // already 'well-formed' object
MyGlobalConstuctor.prototype.GlobalFunctionInObject = function...
};
var MyGlobalObj = new MyGlobalConstuctor();
// so I'm sceptical to NEW, because I have ALREADY wrote my functions
// which I expect to be in memory, single instance of each of them,
// so creating MyObject2,3,4 with NEW MyGC() makes no sense to me.
// DO I REALLY HAVE TO USE "MyGlobalConstuctor.prototype." FOR EACH FUNCTION?!!!!
您可以通过调用newCat函数并扩展您得到的对象来继承:
var newCat = function (name) {
return {name: name, purr: function () {alert(name + ' purrs')}};
};
var myCat = newCat('Felix');
myCat.name; // 'Felix'
myCat.purr(); // alert fires
如果需要全局cats对象,请执行以下操作:
var newLion = function (name) {
var lion = newCat(name);
lion.roar = function () {
alert(name + ' roar loudly');
}
return lion;
}
现在您可以拨打:
var cats = (function () {
var newCat = function (name) {
return {
name: name,
purr: function () {
alert(name + ' is purring')
}
};
};
return {
newCat: newCat
};
}());
变异1-混合蛋白
使用此方法,您每次调用newsometype()
,创建其所有方法并将所有此方法添加到新对象时,都将创建一个新对象。每次创建对象时
赞成的意见
- 它看起来像是经典的继承,所以对Java-C#-C++-等人来说很容易理解
- 每个实例可以有私有变量,因为每个创建的对象都有一个函数
- 它允许多重继承,也称为Twitter混合或
SomeType的obj实例将返回true
欺骗
- 随着创建的对象越来越多,它会消耗更多的内存,因为每个对象都会创建一个新的闭包并再次创建它的每个方法
- 私有属性是
私有的
,不受保护
,子类型无法访问它们
- 要知道一个对象是否有某种类型作为超类,并不容易
遗产
SomeType的子实例将返回false除了逐个查看是否有SomeType方法外,没有其他方法可以知道子实例是否有SomeType方法
变体2-带有原型的对象文字
在本例中,您创建的是单个对象。如果您只需要这种类型的一个实例,那么它可能是最好的解决方案
赞成的意见
- 它既快又容易理解
- 性能
欺骗
- 没有隐私,所有财产都是公共的
遗产
您可以继承一个对象并对其进行原型化
var obj = {
publ: "I'm public",
_convention: "I'm public too, but please don't touch me!",
someMethod: function() {
return this.publ + this._convention;
}
};
如果您使用的是旧浏览器,则需要保证对象。创建工作:
var child = Object.create(obj);
child.otherMethod = function() {
return this._convention + this.publ;
};
要知道一个对象是否是另一个对象的原型,可以使用
if (!Object.create) {
Object.create = function(obj) {
function tmp() { }
tmp.prototype = obj;
return new tmp;
};
}
变体3-构造函数模式
更新:这是ES6类的语法模式。如果您使用ES6类,您将遵循这种模式
obj.isPrototypeOf(child); // true
如果不继承,则可以重新分配原型,而不是添加每个方法,并记住重新分配构造函数属性:
function SomeType() {
// REALLY important to declare every non-function property here
this.publ = "I'm public";
this._convention = "I'm public too, but please don't touch me!";
}
SomeType.prototype.someMethod = function() {
return this.publ + this._convention;
};
var obj = new SomeType();
或者如果页面中有下划线或jquery,则使用u.extend或$.extend
SomeType.prototype = {
constructor: SomeType,
someMethod = function() {
return this.publ + this._convention;
}
};
引擎盖下的new
关键字只执行以下操作:
_.extend(SomeType.prototype, {
someMethod = function() {
return this.publ + this._convention;
}
};
你拥有的是一个函数,而不是没有方法;它只有一个带有函数列表的prototype
属性,new
操作符意味着创建一个新对象,并使用此函数的prototype(object.create
)和构造函数
属性作为初始值设定项
赞成的意见
- 性能
- 原型链将允许您知道对象是否继承自某个类型
欺骗
- 两步遗传
遗产
你可能会认为它看起来像一个超级变奏曲集2。。。你是对的。它类似于变体2,但有一个初始化函数(构造函数)
SubType的子实例
和SomeType的子实例
将同时返回true
好奇:在引擎盖下瞬间
操作员所做的是
function SubType() {
// Step 1, exactly as Variation 1
// This inherits the non-function properties
SomeType.call(this);
this.otherValue = 'Hi';
}
// Step 2, this inherits the methods
SubType.prototype = Object.create(SomeType.prototype);
SubType.prototype.otherMethod = function() {
return this._convention + this.publ + this.otherValue;
};
var child = new SubType();
变体4-覆盖\uuuuuuuuuuuuuuuuuuu
在引擎盖下创建(obj)
对象时
function isInstanceOf(obj, Type) {
return Type.prototype.isPrototypeOf(obj);
}
\uuu proto\uu
属性直接修改对象的隐藏[Prototype]
属性。因为这会破坏JavaScript行为,所以它不是标准的。首选标准方式(Object.create
)
赞成的意见
- 灵巧
欺骗
- 非标准
- 危险的;由于
\uuuuu proto\uuuu
键可以更改对象的原型,因此无法拥有哈希映射
遗产
评论问题
1.var1:在某个类型中发生了什么。调用(这个)?“呼叫”是特殊功能吗?
哦,是的,函数是对象,所以它们有方法,我要提到三个:,和
对函数使用.call()时,可以在函数内部传递一个额外的参数,即上下文、this
的值,例如:
var child = { __proto__: obj };
obj.isPrototypeOf(child); // true
因此,当我们执行SomeType.call(this)
时,我们将对象this
传递给函数SomeCall
,正如您所记得的,此函数将向对象this
添加方法
2.var3:你说的“真正定义属性”是指我在函数中使用它们吗
_.extend(SomeType.prototype, {
someMethod = function() {
return this.publ + this._convention;
}
};
function doNew(Constructor) {
var instance = Object.create(Constructor.prototype);
instance.constructor();
return instance;
}
var obj = doNew(SomeType);
function SubType() {
// Step 1, exactly as Variation 1
// This inherits the non-function properties
SomeType.call(this);
this.otherValue = 'Hi';
}
// Step 2, this inherits the methods
SubType.prototype = Object.create(SomeType.prototype);
SubType.prototype.otherMethod = function() {
return this._convention + this.publ + this.otherValue;
};
var child = new SubType();
function isInstanceOf(obj, Type) {
return Type.prototype.isPrototypeOf(obj);
}
function fakeCreate(obj) {
var child = {};
child.__proto__ = obj;
return child;
}
var child = fakeCreate(obj);
var child = { __proto__: obj };
obj.isPrototypeOf(child); // true
var obj = {
test: function(arg1, arg2) {
console.log(this);
console.log(arg1);
console.log(arg2);
}
};
// These two ways to invoke the function are equivalent
obj.test('hi', 'lol');
// If we call fn('hi', 'lol') it will receive "window" as "this" so we have to use call.
var fn = obj.test;
fn.call(obj, 'hi', 'lol');
function A() { }
// When you create a function automatically, JS does this:
// A.prototype = { constructor: A };
A.prototype.someMethod = function() {
console.log(this.constructor === A); // true
this.constructor.staticMethod();
return new this.constructor();
};
A.staticMethod = function() { };
A.prototype = {
someMethod = function() {
console.log(this.constructor === A); // false
console.log(this.constructor === Object); // true
this.constructor.staticMethod();
return new this.constructor();
}
};