Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
可重用javascript对象、原型和范围_Javascript_Scope_Prototype - Fatal编程技术网

可重用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();  
    }
};