gpt4 book ai didi

javascript - JavaScript:对象继承自Function.prototype

转载 作者:行者123 更新时间:2023-11-29 10:40:44 26 4
gpt4 key购买 nike

我正在测试James Shore的Object Playground,发现所有方法都继承自Function.prototype,包括全局Object.prototype上的方法。这是如何运作的?那不是通函吗?我的意思是... Object.prototype固有的Function.prototype不是“自身”吗?那么Object如何从Function.prototype继承任何东西呢?函数不仅是Object的子类型吗?对象不应该固有地包含这些行为吗?为什么需要这种继承?

最佳答案

TL; DR

Object.prototype 是原型(prototype)链中的最后一个,它不继承任何东西。 对象构造函数是从 Function.prototype 继承的构造函数,因为它只是一个函数。这是一个Function实例。

长版

由于您的问题是一个笼统的问题,因此我将尝试描述一些主题,希望您能回答自己的问题。以下是我将尝试涵盖的主题:

  • 使用“prototype”一词的两种方法。
  • 如何在JavaScript中创建类。
  • 函数对象构造函数之间的关系。

  • 注意:很难解释JavaScript的真正工作原理。我希望您能从中学到一些东西。

    使用“原型(prototype)”一词的两种方法

    在JavaScript中,“原型(prototype)”一词可能会有些困惑。这是因为根据上下文,至少有两种使用该词的方法:

    1)“另一个对象的 原型(prototype)对象

    另一个对象的原型(prototype)对象也称为“内部原型(prototype)”,表示为[[Prototype]]或 __proto__;他们都是同一件事。作为示例,我们使用以下数组: nums = [9, 8, 7];。我们说 nums是一个数组...但是为什么呢?
  • 我们说这是一个数组,因为它是Array构造函数的实例(构造函数只是函数,除了我们将它们与新的关键字一起使用外)。
  • 我们也说这是一个数组,因为它的原型(prototype)对象(也称为“内部原型(prototype)”)是Array.prototype属性内部包含的对象。

  • 2)“构造函数的 原型(prototype)属性

    继续 nums数组示例,Array构造函数具有一个名为 prototype的属性,我们可以像这样访问它: Array.prototype。此属性是Array实例的“内部原型(prototype)”,并提供了我们用于调用数组的所有方法-例如 forEachpushpopjoin等。

    因此,同样,我的函数 foo()或任何其他函数的内部原型(prototype)是 Function.prototype属性内所包含的对象。换句话说, Function.prototype是任何函数的“内部原型(prototype)”对象。另外,我们可以说Function构造函数具有prototype属性,该属性最终是所有函数的“内部原型(prototype)”。

    我要讲的是我们用两种不同的方式谈论一件事(原型(prototype))。第一种方式,我们说:对象的“原型(prototype)/内部原型(prototype)”,第二种方式,我们说:“构造函数的原型(prototype)”属性。

    如何在JavaScript中创建类

    在JavaScript中, 构造函数类似于其他编程语言中的 。好吧,不完全是。实际上,为了类似于类,JavaScript使用了构造函数和另一个称为 原型(prototype)的对象的组合。实际上,每个JavaScript函数都会自动获取原型(prototype)属性,因为函数可以用作构造函数或简单地用作函数。当一个函数不被用作构造函数时,它的prototype属性不被用于任何东西,而只是悬而未决。

    在古典语言中,类同时包含实例变量和实例方法,但是在JavaScript中,构造函数包含实例变量,而其原型(prototype)对象包含实例方法。

    实例变量对于构造函数的特定实例是唯一的(它们包含实例特定的数据),并且实例方法由所有实例共享。换句话说,所有实例都可以执行实例方法,但不能访问彼此的变量。

    因此,JavaScript中的所有对象都是其各自的构造函数的实例。例如,诸如 [1,2,3]的数组是 function Array() {}构造函数的实例。诸如 {key: 'value'}之类的对象是 function Object() {}构造函数的实例。 JavaScript函数(例如 alert())是 function Function() {}构造函数的实例……等等。

    同样,JavaScript中的所有构造函数都具有 prototype属性,并且此属性包括构造函数实例将继承的方法。

    示例:
    // Person constructor to create people instances
    function Person(name, age) {
    // Every instance has its own "instance variables", a.k.a. properties.
    this.name = name;
    this.age = age;
    }


    // The "instance methods"
    Person.prototype = {
    greet: function() {
    return 'Hello ' + this.name;
    },
    //...
    };


    // Joe is an instance of the `Person` constructor, and Joe's "prototype"
    // is the `Person.prototype` object. We call Joe's "prototype" the
    // "internal prototype".
    var joe = new Person('Joe Doe', 44);
    joe.name; //=> Joe Doe
    joe.greet(); //=> Hello Joe Doe

    函数和对象构造函数之间的关系
    Object构造函数。

    对象构造函数与上面的Person构造函数一样,只是它创建对象实例而不是person实例。
    Function构造函数。

    函数构造函数与上面的Person&Object构造函数一样,除了它创建Function实例,换句话说,它创建函数。

    JavaScript中的所有构造函数(例如 PersonObjectArrayFunctionStringBoolean等等)都是函数。由于它们是函数,因此意味着它们是使用该语言在内部使用 new Function创建的,并且所有函数方法(例如 call()apply())都来自 Function.prototype 。换句话说,Function.prototype是所有函数(包括构造函数和函数 Function本身)的“原型(prototype)/内部原型(prototype)”对象。

    结论:

    不要混淆构造函数的 prototype属性,该属性包括将来的实例将使用的方法,以及构造函数本身的内部原型(prototype)。

    但是,请记住,构造函数的 prototype属性是该构造函数实例的内部[[Prototype]]。例如, Function.prototypeObject构造函数的内部[[Prototype]],这是有道理的,因为 Object构造函数只是另一个函数(一个 Function实例)。

    对于代码结论,请看一下如何在JavaScript内部创建Object&Function构造函数:
    // Object constructor
    // ==============================================
    function Object() { /* ... */ }
    // Object.keys()
    // Object.observe()
    // ...


    // `Object.__proto__` (internal [[Prototype]])
    // -----------------------------------------------
    // Since `Object` is a function, it inherits all of Function's
    // instance methods (the ones inside of Function.prototype).
    //
    // In other words the `Object` constructor can use methods
    // like `apply()`, `call()`, `bind()`, and more.
    //
    // So we can say that the Object's prototype is the
    // `Function.prototype` object.
    Object.__proto__ = Function.prototype;


    // `Object.prototype` (instance methods)
    // -----------------------------------------------
    // The Object's `prototype` property is totally different from
    // the `__proto__` property. This `prototype` property includes
    // methods that all JavaScript objects inherit. So an object
    // literal like `var obj = {}` or an array like `var arr = []`
    // or even a function like `alert` can use these methods.
    Object.prototype = {
    constructor: Object,
    hasOwnProperty: function() {},
    isPrototypeOf: function() {},
    //...
    };



    // Function constructor
    // ==============================================
    function Function() { /* ... */ }
    // Function.call()
    // Function.apply()
    // ...


    // [[Prototype]] + instance methods
    // -----------------------------------------------
    // Since `Function` is a function itself and at the same time
    // the constructor for other JavaScript functions, its internal
    // [[Prototype]] and the `prototype` property point to the same
    // exact object.
    Function.__proto__ = Function.prototype = {
    apply: function() {},
    call: function() {},
    bind: function() {},

    //...

    // Just an object literal, so it inherits the
    // Object's instance methods.
    __proto__: Object.prototype
    };

    更多资源
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Determining_instance_relationships
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
  • https://es5.github.io/#x15.3.4
  • http://people.mozilla.org/~jorendorff/es5.1-final.html#sec-15.3.2.1;将为每个函数自动创建一个原型(prototype)属性,以提供将该函数用作构造函数的可能性。
  • https://www.quora.com/In-JavaScript-what-is-the-logic-behind-the-data-structure-of-function-prototype-proto-and-constructor?share=1
  • 关于javascript - JavaScript:对象继承自Function.prototype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29813074/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com