JavaScript函数对象的属性(Properties of Javascript functio

2019-07-20 19:59发布

我有一个JavaScript函数对象;

var addNum = function(num1, num2) {
        return num1 + num2;
}

现在,如果我尝试访问

addNum.divide()

我想了解上面的代码原型链。 我读的是,在上述例子中,将addNum被搜索除(),随后Function.prototype的最后的Object.prototype。

但我的问题是,在上面的例子中,如何addNum会被搜索鸿沟()

它指的是这样;

var addNum = function(num1, num2) {

this.divide = function(){}

            return num1 + num2;
    }

它说:addNum将搜索鸿沟我也不懂行的()

请帮助我了解的一样。

Answer 1:

我不知道这会回答你的问题,但可以给你一些启示。 请看下面的例子:

var Person = (function () {
    var Person = function (name) {
        this.name = name;
    }

    Person.greet = function () {
        console.log("Hello!");
    }

    Person.prototype = {
        greet: function () {
            console.log('Hello, my name is ' + this.name);
        }
    };
    return Person;
})();

var bob = new Person("Bob");

Person.greet(); // logs "Hello!"
bob.greet(); // logs "Hello, my name is Bob

该函数对象“人”有着直接的“打招呼”属性,它是一个功能。 OOP的角度来看,你几乎可以想到的,作为一个静态方法,可以直接从人函数被调用(Person.greet())。 一旦你“实例”,从人构造一个Person对象,即新对象“鲍勃”现在的方法引用从Person.prototype的对象。 现在,当你调用bob.greet(),它使用的原型对象的greet函数。

希望帮助。



Answer 2:

正如你这么说自己: 你有一个函数对象 。 函数是在JS对象,就像对象常量数组,或其他任何东西:一个函数可以随意分配的属性和方法:

var someAnonFunction = function(foo)
{
    console.log(this);
    console.log(this === someAnonFunction);//will be false most of the time
};
someAnonFunction.x = 123;//assign property
someAnonFunction.y = 312;
someAnonFunction.divide = function()
{
    console.log(this === someAnonFunction);//will be true most of the time
    return this.x/this.y;//divide properties x & y
};
someAnonFunction.divide();

在这种情况下,功能对象,通过引用someAnonFunction已经被分配了参考匿名功能,称为divide (以及,提及一个匿名函数被冠以除法反正)。 所以,在这里都没有原型的参与。 你要知道,你这样自己说:所有的对象都可以追溯到Object.prototype ,只是试试这个:

console.log(someAnonFunction.toString === Function.prototype.toString);//functions are stringified differently than object literals
console.log(someAnonFunction.hasOwnProperty === Object.prototype.hasOwnProperty);//true

或者,也许这更是明确表示:方法/属性调用是如何解决在JS值的简单方案:

[      F.divide      ]<=========================================================\ \
F[divide] ===> JS checks instance for property divide                           | |
 /\ ||                                                                          | |
 || || --> property found @instance, return value-------------------------------| |
 || ||                                                                          | |
 || ===========> Function.prototype.divide could not be found, check prototype  | |
 ||      ||                                                                     | |
 ||      ||--> property found @Function.prototype, return-----------------------| |
 ||      ||                                                                     | |
 ||      ==========> Object.prototype.divide: not found check prototype?        | |
 ||          ||                                                                 | |
 ||          ||--> property found @Object.prototype, return---------------------|_|
 ||          ||                                                                 |=|
 ||          =======>prototype is null, return "undefined.divide"~~~~~~~~~~~~~~~|X|
 ||                                                                             \ /
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~< TypeError can't read property 'x' of undefined

由此得出,如果你想上面的代码中使用原型的工作,你必须增加一个原型各种各样的(在这种情况下, Function.prototype )。 知道这是不被推荐的,其实改变“原生”的原型时经常皱眉。 仍然:

Function.prototype.divide = function (a, b)
{
    a = +(a || 0);//coerce to number, use default value
    b = +(b || 1) || 1;//division by zeroe is not allowed, default to 1
    return a/b;
};
function someFunction ()
{
    return 'someString';
};
var another = function(a, b)
{
    return a + b;
};
someFunction.divide(12, 6);//will return 2
another.divide(12, 4);//3

在这两种情况下,所述功能对象,由名称(引用someFunctionanother )将被扫描的一个名为属性divide ,这是没有找到。 然而然后它会扫描Function.prototype ,在这样的属性没有被找到。
如果不是这样的话,JS也将检查Object.prototype ,如果失败了,它最终将抛出一个错误。

我已经张贴在SO相当长的回答上这个问题而回:

是什么让my.class.js这么快? (与原型链交易)
在javascript对象和函数 (的<=>对象功能概括<=>构造函数)
什么是JavaScript中的“类”的定义这三种模式之间的差异? (一些更多的信息,仍然)
使用Javascript -动态改变函数的内容 (隐约倒是匿名函数,赋值给变量和属性,并改变它们的上下文)



Answer 3:

您可以创建divide为[不大不小的的] static方法:

var addNum = function(num1, num2) {
  addNum.divide = function(){return num1/num2;};
  return num1 + num2;
}
// now you first have to run addNum
var onethirds = addNum(1,3); //=> 4
addNum.divide(); //=> 0.333333...

但它是不可取的。 更好地创造一个构造函数:

function Pair(n1,n2){
   n1 = n1 || 1;
   n2 = n2 || 1;
   // create instance methods
   this.add      = function(){return n1+n2;};
   this.divide   = function(){return n1/n2;};
   this.multiply = function(){return n1*n2;}
}
var pair1 = new Pair(2,6)
   ,pair2 = new Pair(1,2);
pair1.add();    //=> 8
pair2.divide(); //=> 0.5
//etc.

或者更原型方法(方法添加到构造函数的原型,而不是每个实例):

function Pair(n1,n2){
   this.n1 = n1 || 1;
   this.n2 = n2 || 1;
   // create prototype methods (once)
   if (!Pair.prototype.add){
    var proto      = Pair.prototype;
    proto.add      = function(){return this.n1+this.n2;};
    proto.divide   = function(){return this.n1/this.n2;};
    proto.multiply = function(){return this.n1*this.n2;}
   }
}

阅读的东西



Answer 4:

不,你的最后一个代码才有意义,如果你使用addNum作为一个构造函数:

var instance = new addNum();
instance.divide();

然而,因为函数是对象,下面是有效的:

var addNum = function(num1, num2) {
        return num1 + num2;
}
addNum.divide = function() {}

在这种情况下divide将是一个财产addNum本身,而不是它的原型之一。



Answer 5:

要理解原型继承起初有点模糊,但认为它顾名思义,也有JavaScript的一些原型,功能就是其中之一。

当你创建一个新的功能,你可以检查它与类型typeof命令。 你的情况:

var a = function(a,b) { return a + b; }

它会返回"function"所以有两种方式添加到您的a变量的详细方法。 其中之一是,作为@Keith莫里斯建议,创建一个新的构造,并有其方法内返回。 这也是首选方法,因为这样,你不污染与扩展到每一个对象是他们所代表原型方法的基本对象。

也就是说,如果我不是这样做:

Function.prototype.divide = function(a, b) { return a / b; }

我现在可以做a.divide(2, 1); 并且它会返回2 。 但是,例如,如果我使用jQuery ,做jQuery.divide(2,1)我也将获得2 ,因为它试图找到它在功能上的直接范围。 如果不是,它会去到它的原型。

希望这是向你解释好一点。



文章来源: Properties of Javascript function objects