是否可以在没有prototype属性的情况下将方法附加到构造函数/函数?

时间:2017-10-19 06:23:41

标签: javascript constructor prototype

function DoIHavePrototype()
{
    var a = 10;
}

CheckIt = new DoIHavePrototype();

DoIHavePrototype.prototype.GetFnName = function()
{
    return "DoIHavePrototype"
}

alert(CheckIt.GetFnName())

在上面的代码中,我观察到prototype是函数的内置属性,我们可以使用它将属性/方法附加到函数中。

但是,如果我删除上述代码中的prototype关键字,如下所示:

DoIHavePrototype.GetFnName = function()
    {
        return "DoIHavePrototype"
    }

我没有在函数定义中出错,而是在调用方法时遇到错误 alert(CheckIt.GetFnName())为“CheckIt.GetFnName不是函数”

JS解释器假设这是什么?

3 个答案:

答案 0 :(得分:1)

如果您仍想将其用作实例方法,也可以这样做。

{
    "response": {
        "players": [
            {
                "steamid": "76561198301407459",
                "communityvisibilitystate": 3,
                "profilestate": 1,
                "personaname": "SlothGod",
                "lastlogoff": 1508389707,
                "commentpermission": 1,
                "profileurl": "http://steamcommunity.com/id/sleuthgud/",
                "avatar": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba.jpg",
                "avatarmedium": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba_medium.jpg",
                "avatarfull": "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/09/09cea52b91136fb3306c57771a746db2823b91ba_full.jpg",
                "personastate": 0,
                "realname": "Josh",
                "primaryclanid": "103582791460168790",
                "timecreated": 1462086929,
                "personastateflags": 0,
                "loccountrycode": "AU",
                "locstatecode": "QLD"
            }
        ]

    }
}

答案 1 :(得分:1)

如果您将函数直接附加到类中,它将生成所谓的static method,您只能在Array.from中调用您的类。  所以在你的情况下你应该使用你的类(而不是它的实例)来调用它,就像DoIHavePrototype.GetFnName();

一样

您可以在MDN

上阅读此内容

答案 2 :(得分:1)

为了能够在对象上调用某个函数的方法,有4种方法可以将它引入到对象中。

第一种方法是你在原始代码中所做的,即将函数分配给对象原型:

Foo.prototype.myFunc = function () { .... }

另一种方法是将其分配给构造函数中的this

function Foo() {
  this.myFunc = function () { .... }
}

我们也可以直接将它分配给实例:

var foo = new Foo();
var myFunc = function () { .... }
foo.myFunc = myFunc

最后,我们可以将一个函数绑定到实例:

var foo = new Foo();
var myFunc = function () { .... }
var myFuncFoo = myFunc.bind(foo)

最后一种情况有点特殊,因为我们有一个不是实例属性的函数,但行为类似于实例方法,因为它的调用上下文附加到实例上。

定义实例方法的最常用方法是分配原型。构造函数上的prototype属性是实例继承的属性,因此这就是我们放置东西的地方。重要的是要记住,实例继承自prototype属性,而不是构造函数。将任何内容分配给构造函数属性不会使其可用作实例属性。

如果我们想要一个绑定的方法,有时可以使用this的赋值。例如:

function Foo() {
  this.boundMeth = this.meth.bind(this)
  this.val = "foo"
}

Foo.prototype.meth = function () { 
  console.log(this.val)
}

如果我们想将instance.boundMeth()作为值传递给另一个函数(例如,事件处理程序),这将非常有用。在JavaScript中,与许多OO语言不同,方法是未绑定的:

// Using Foo from the previous example

function runner(fn) {
  fn()
}
var obj = new Foo()

runner(obj.meth)  // Logs `undefined`
runner(obj.boundMeth) // Logs `foo`

分配给构造函数原型时,您可以批量分配:

Foo.prototype = {
  meth1: function () { .... },
  meth2: function () { .... },
}

如果您使用ES6,还可以使用class关键字:

class Foo {
  myFunc() { .... }
}

这与Foo.prototype.myFunc = function () { .... }相同。