【问题标题】:What does 'is an instance of' mean in Javascript?Javascript中的“是一个实例”是什么意思?
【发布时间】:2011-08-09 20:25:58
【问题描述】:

这个问题的答案: What is the initial value of a JavaScript function's prototype property?

有这句话:

任何新创建的 Function 实例的原型初始值都是 Object 的新实例

据我所知,Javascript 没有类,因此“实例”这个词在我的脑海中没有意义。应该如何解释 Javascript 中的“实例”?

抱歉,我没有足够的代表将我的问题放在该答案的评论线程中。

【问题讨论】:

    标签: javascript function object instance


    【解决方案1】:

    你说得对,JavaScript 还没有类,但它确实有构造函数,一个定义对象和构造函数之间关系的instanceof 运算符,以及一种基于原型链的继承形式。

    ctor.prototypeobj 的原型链上时,obj instanceof ctor 为真。

    以下面的警告为模,您可以在 EcmaScript 5 中实现 instanceof

    function isInstanceOf(obj, ctor) {
      var proto = ctor.prototype;
      if (typeof obj === "object" || typeof obj === "function") {
        while (obj) {
          if (obj === proto) { return true; }
          obj = Object.getPrototypeOf(obj);
        }
      }
      return false;
    }
    

    除非您重新分配原型 (o = new MyConstructor(); MyConstructor.prototype = somethingElse),否则应该是 new MyConstructor() instanceof MyConstructor

    15.3.5.3 部分详细解释了这一点。

    15.3.5.3[[HasInstance]] (V)

    假设 F 是一个 Function 对象。

    当 F 的 [[HasInstance]] 内部方法调用值为 V 时,采取以下步骤:

    1. 如果 V 不是对象,则返回 false。

    2. 令 O 为调用 F 的 [[Get]] 内部方法的结果,属性名为“prototype”。

    3. 如果 Type(O) 不是 Object,则抛出 TypeError 异常。

    4. 重复

      1. 令 V 为 V 的 [[Prototype]] 内部属性的值。
      2. 如果 V 为 null,则返回 false。
      3. 如果 O 和 V 引用同一个对象,则返回 true。

    这不是全部,因为允许宿主对象(如 DOM 节点)实现 [[HasInstance]] 内部方法,但他们喜欢但大多数浏览器实现宿主对象以尽可能接近原生对象。

    【讨论】:

    • 不要说(yet) :( 课程仍然是稻草人。如果我们幸运的话,他们不会进入 ES6 !
    【解决方案2】:

    JavaScript 没有类,但它有类型。您可以定义自己的类型并使用 new 关键字创建新实例:

    function Foo(initialValue) {
        this.value = initialValue || 0;
    }
    var foo = new Foo(17);
    var fooIsAFoo = foo instanceof Foo;  // true!
    var fooIsAnObject = foo instanceof Object; // also true!  We have inheritance here :)
    

    【讨论】:

    • 您能否通过参考规范支持Types 的概念?我感觉只有原生类型,Foo 不是类型。
    【解决方案3】:

    在 JS 中,函数是一个对象。这需要一段时间才能习惯,但这是事实。稍微考虑一下,您看到其他人使用的代码会更有意义。如果你见过 Javascript 中人们将 function(){} 作为参数传递给另一个函数,那就证明函数是第一类对象。

    一旦你能理解这一点(我花了一段时间),那么你需要明白,如果你创建一个函数,你可以获得它的一个 New 实例。见以下代码:

    function FooName(){
        var name;
        this.setName = function(n){
            this.name = n;
        }
        this.getName = function(){
            return this.name;
        }
    }
    var n1 = new FooName();
    var n2 = new FooName();
    n1.setName("FOO");
    n2.setName("BAR");
    

    此时,您有 FooName 方法的两个实例:n1 和 n2。在 JS 中使用大写首字母而不是客户的小写首字母命名可实例化函数是一种约定。在这个例子中,我指出我的函数可以通过将其命名为 FooName 而不是 fooName 来实例化。我希望这是有道理的。

    在上面的示例中,n1 具有三个属性。一个私有名称属性、一个公共 setName 属性和一个公共 getName 属性。每次我实例化一个新的 FooName 时,都会创建一个 getName 和 setName 的副本。这会浪费内存空间。由于 getName 和 setName 不会改变,我不需要为每个 FooName 实例创建一个新副本。这就是原型的用武之地。

    你可以这样说,那么getName和setName在内存中只会存在一次,这样就可以释放内存,这是一件好事。

    FooName.prototype.setName = function(n){
        this.name = n;
    }
    FooName.prototype.getName = function(){
        return this.name;
    }
    

    如果您从 FooName 函数中删除 getName 和 setName,那么现在您将拥有一个 FooName“类”,它有两个方法,getName 和 setName。

    玩它。如果您有任何问题,请告诉我。

    【讨论】:

    • 不确定这是否回答了@lodrup 的问题,但它确实给了我一些见解。谢谢+1
    • True...我想我会说“instanceof”意味着你有一个函数,并且已经声明了一个新的。关键词“新”是什么会给你实例。例如,我上面的代码,var n3 = FooName 与 var n3 = new FooName 不同。留下新的差异是非常重要的。如果您将“新”排除在外,那么“this”一词的所有用法都将指代窗口本身。 JS 中的“this”是指调用它的上下文。如果在 obj 实例中调用它,它指的是 obj。如果你在 obj 实例之外调用它,它是全局的。
    • "如果您从 FooName 函数中删除 getName 和 setName,那么现在您将拥有一个 FooName“类”,它有两个方法,getName 和 setName。"也就是说,(function-)-object FooName 的原型对象现在具有这些函数,并且由于能够遵循原型链的名称解析方法, FooName 的所有实例都将能够找到这些方法。你是这个意思吗?
    【解决方案4】:

    在 JavaScript 中,函数是一等对象,这意味着您可以像对待任何对象一样对待它们。

    //定义类

       function User(name,age)
        {
            this.Name=name;
            this.Age=age
        }
    

    //创建实例

    var user1= new User('Demo1','50');
    var user2= new User('Demo2','100');
    
    
    alert(user1.Name);
    alert(user2.Name);
    

    http://jsfiddle.net/praveen_prasad/hmUku/

    http://en.wikipedia.org/wiki/First-class_function

    【讨论】:

      【解决方案5】:

      Javascript 不使用经典继承,它使用prototypal inheritance,其中一切都是“对象”,继承是通过克隆完成的,例如:

      var myPrototype = function() {
         var privateMember = "I am private";
         var publicMember = "I am public";
         var publicMethod = function () {
             alert(privateMember); 
         }
         return {
            publicMember = publicMember,
            publicMethod = publicMethod
         }
      }
      
      var myInstace = new myPrototype();
      myInstance.publicMethod();
      

      这里的myInstance 可以说是myPrototype 的“实例”,但实际上发生的情况是使用您克隆myPrototypenew 关键字创建myInstance

      【讨论】:

        【解决方案6】:

        所以现在我制作了一个页面来描述我认为你们所有人*在说什么: https://docs.google.com/document/d/1VvqqO2LMmilLbIvcU2JHI9ifaoMs-DB-farEzwuVuwM/edit?hl=da

        用漂亮的图形说明:)

        问候乔恩

        *和这个链接: http://trephine.org/t/index.php?title=Understanding_the_JavaScript_new_keyword

        【讨论】:

          【解决方案7】:

          Javascript 是面向对象的,所以它确实有类。根本没有明确的“类”指令,就像在其他 OOP 语言中那样。

          【讨论】:

          • Javascript 没有类,它是一种基于原型的语言,是实现 OOP 的不同方式。差异可能很细微,但很重要。
          猜你喜欢
          • 1970-01-01
          • 2017-06-11
          • 1970-01-01
          • 2017-12-06
          • 2013-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多