【问题标题】:Javascript Do object literals have prototype property? [duplicate]Javascript 对象文字是否具有原型属性? [复制]
【发布时间】:2020-06-21 00:21:07
【问题描述】:

当了解 Javascript 中的 3 种广泛类型的对象,即字面量、函数对象和函数对象时, 我在某处读到文字对象没有函数对象(或构造函数)之类的原型属性。 这会是一个真实的说法吗?

我问这个的原因是因为我们可以做到;

var person = {
fn: 'ABC'
}
person.__proto__ = someObj;

不确定是否真的允许所有浏览器都允许使用“proto”进行此设置,这就是该声明不正确的原因?

对于“来自函数的对象”也是如此吗?即当我们执行“new SomeFunctionObject()”时

【问题讨论】:

    标签: javascript prototype


    【解决方案1】:

    我在某处读到文字对象没有函数对象(或构造函数)之类的原型属性。

    这听起来像是在引用名为.prototype 的属性,这是真的。一个function 和一个class 将自动接收一个.prototype 属性,该属性包含一个属性(constructor,指向类/函数本身)并继承自Object.prototype

    您问题中的陈述是正确的。只有可调用的类类对象——类和functions——会自动接收这些类型的属性。其他对象没有:

    class Foo {
    }
    function Foo2() {
    }
    const obj = {};
    
    console.log(
      Foo.prototype,
      Foo2.prototype,
      obj.prototype
    );

    关于您问题中的代码,允许使用__proto__,但已弃用。作为MDN says

    警告:虽然Object.prototype.__proto__ 目前在大多数浏览器中都受支持,但它的存在和确切行为仅在 ECMAScript 2015 规范中作为遗留功能进行了标准化,以确保与 Web 浏览器的兼容性。为了更好的支持,建议改用Object.getPrototypeOf()

    Object.getPrototypeOf 现在应该是首选。

    即当我们执行“new SomeFunctionObject()”时

    当您使用new 创建实例时,新实例的内部原型(通常)将与构造函数的.prototype 属性是相同的对象。也就是说,使用以下代码:

    class Foo {
      // anything
    }
    const f = new Foo();
    

    f 实例的内部原型将与Foo.prototype 是同一个对象。

    class Foo {
      // anything
    }
    const f = new Foo();
    console.log(
      Object.getPrototypeOf(f) === Foo.prototype,
      f.__proto__ === Foo.prototype,
    );

    实例的内部原型与构造函数的.prototype 相同的唯一情况是构造函数显式返回一个对象,这有点不寻常。

    class Foo {
      constructor() {
        return {};
      }
    }
    const f = new Foo();
    console.log(
      Object.getPrototypeOf(f) === Foo.prototype,
      f.__proto__ === Foo.prototype,
    );

    【讨论】:

      【解决方案2】:

      函数有一个prototype 属性,它继承自 Object。

      function Person(last, first, middle){
        // constructors allow private variables that can be shared across methods without the use of `this.` - API developers may accidentally access properties meant to be private in classes, so use constructors
        const proto = Person.prototype;
        if(last !== undefined){
          this.last = last; this.first = first; this.middle = middle;
        }
        this.getFullName = (lastFirst = false)=>{
          const m = this.middle ? ' '+this.middle : ''
          if(lastFirst){
            return this.last+', '+this.first+m;
          }
          return this.first+m+' '+this.last;
        }
        this.setFullName = (last, first, middle)=>{
          proto.last = this.last = last; proto.first = this.first = first; 
          proto.middle = this.middle = middle;
          return this;
        }
      }
      console.log(typeof Person);
      const bob = new Person('Smith', 'Bob', 'Gene');
      console.log(bob.getFullName());
      const james = new Person('Brown', 'James');
      console.log(james.getFullName(true));
      bob.setFullName('Static', 'Method', 'like');
      const person = new Person;
      console.log(person.getFullName()+' -- sort of');
      console.log(typeof person);

      请注意,构造函数的 new 实例返回 new 对象字面量。

      【讨论】:

        【解决方案3】:

        你可以使用这个设置prototype

        Object.setPrototypeOf(obj, prototype)
        

        您还可以阅读文档here

        【讨论】:

          【解决方案4】:

          如果你显式地给一个对象的proto赋值,当然现在这个对象就有了prototype属性。当你只是给一个对象赋值时,它目前还没有原型。这个属性在跨浏览器的兼容性上存在一些问题。 new Con() 构建的对象当然具有原生的原型属性。

          【讨论】:

          • 但是对于由 new Con() 构建的对象,它的原型会自动设置为 Con.prototype 设置的任何内容...不是吗?或者它仍然可以明确设置吗?
          • 是的,这在 JS 中称为继承。确实可以显式设置,但是从 proto 获取一些属性或方法时会改变原型链
          猜你喜欢
          • 2011-12-17
          • 2013-09-26
          • 2017-01-09
          • 2014-05-08
          • 2021-12-03
          • 1970-01-01
          • 2019-01-23
          • 2023-03-27
          • 2013-12-26
          相关资源
          最近更新 更多