1

方法(对象的函数)可以使用“this”关键字来引用对象的变量。

函数的属性可以引用函数变量吗?

例如:-

   function foo()
    {
        var x=5;
    }
    foo.help = {o1:x};// o1 is not initialized to x.
//Using o1:this.x also doesn't help. Why? Explain please.

无论如何将o1初始化为x?

示例 9-1。一个简单的 JavaScript 类

// range.js: A class representing a range of values.
// This is a factory function that returns a new range object.
function range(from, to) {
// Use the inherit() function to create an object that inherits from the
// prototype object defined below. The prototype object is stored as
// a property of this function, and defines the shared methods (behavior)
// for all range objects.
var r = inherit(range.methods);
// Store the start and end points (state) of this new range object.
// These are noninherited properties that are unique to this object.
r.from = from;
r.to = to;
// Finally return the new object
return r;
}
// This prototype object defines methods inherited by all range objects.
range.methods = {
// Return true if x is in the range, false otherwise
// This method works for textual and Date ranges as well as numeric.
includes: function(x) { return this.from <= x && x <= this.to; },
// Invoke f once for each integer in the range.
// This method works only for numeric ranges.
foreach: function(f) {
for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);
},
// Return a string representation of the range
toString: function() { return "(" + this.from + "..." + this.to + ")"; }
};
// Here are example uses of a range object.
var r = range(1,3); // Create a range object
r.includes(2); // => true: 2 is in the range
r.foreach(console.log); // Prints 1 2 3
console.log(r); // Prints (1...3)

我的理解: Range 是一个具有变量 from 和 to 的函数。Range.methods 是 Range 的属性。它在 Range() 之外定义,但它仍然可以访问 from 和 to(使用 this.from 和 this.to )。如何?谢谢你。

4

2 回答 2

3

编辑

此答案基于已编辑的问题-原始答案如下


你的理解有点落后。
该功能没有 from并且to以您认为的方式。

如果我以不同的方式构建它,以获得几乎所有相同的功能,但对于 JS 新手来说更容易理解,我会这样写:

// my `makeRange` function makes an object
// then it gives it all of the things a range object needs
// then it returns the new object
var makeRange = function (min, max) {
    // there are cleaner more-compact ways of doing this
    // I'm writing this out in long-form to show you exactly what's going on
    var rangeObject = {};
    rangeObject.from = min;
    rangeObject.to = max;
    rangeObject.includes = includes;
    rangeObject.foreach  = foreach;
    rangeObject.toString = toString;

    return rangeObject;
};

// these are all of the functions inside of `range.methods`
// they don't have to be attached to the function ***AT ALL***, for ***ANY REASON***
// other than the author wanted them to be there for the sake of organization
// Here, I'm just putting them out on their own, for sake of clarity
var includes = function (x) { return this.from <= x && x <= this.to; },
    foreach  = function (func) {
        var min = this.from,
            max = this.to,
            i   = 0;

        for (i = min; i <= max; i += 1) { func(i); }
    },
    toString = function () { return "(" + this.from + "..." + this.to + ")"; };



var range_3_to_5  = makeRange(3,  5),
    range_6_to_12 = makeRange(6, 12);


range_3_to_5.from;         // 3
range_6_to_12.includes(8); // true
range_6_to_12.foreach(function (i) { console.log(i); }); // [logs:] 6,7,8,9,10,11,12

示例中的methodsonrange不是函数的一部分。
它们是在构造时赋予对象的方法。
在您给出的示例中,这发生在r = inherit(range.methods);调用内部,该代码块中没有解释。

this根本不涉及该功能。
它指的是在调用方法时使用方法的最终对象

range_3_to_5range_6_to_12都使用相同的includes.
range_3_to_5.includes(6);被调用时,this设置为range_3_to_5,然后该函数使用this.fromandthis.to来确定是否x在范围内。

这里没有复杂的魔法。
我们只是调用一个以特定方式“制造”某些东西的函数,例如工厂装配线,然后将完成的版本传递出去。

它将共享函数附加到装配线上的每个副本,这些共享函数用于this确定他们当时正在处理的副本。

var car   = { license : "a32 vx98" },
    truck = { license : "vdx 2000" },
    jeep  = { license : "mkv 3a2b" };


var read_license = function () { console.log(this.license); };


car.read_license   = read_license;
truck.read_license = read_license;

car.read_license();   // [logs:] a32 vx98
truck.read_license(); // [logs:] vdx 2000

我什至可以自己调用函数,使用函数.call.apply方法手动设置this.

read_license.call(jeep); // [logs:] mkv 3a2b

或用于.bind保存始终使用相同值的函数版本this

var read_car_license = read_license.bind(car);

read_car_license();  // a32 vx98

下面的上一个答案


甚至远程也不行。

变量存在于创建它们的函数中:

var myFunction = function () {
    var myValue = 23;
    console.log(myValue);
};


myFunction(); // [log:] 23
console.log(myValue); // undefined

值可以进一步存在于函数内部:

var myFunction = function () {
    var myValue = 23,

        sayValue = function () {
            console.log(myValue);
        };


    sayValue();  // will log 23 when you call `myFunction`
}



myFunction();  // [log:] 23

但是,如果您希望您的变量位于函数的外部(而不是更远的内部),那么您需要将值返回给某个东西,或者直接从函数内部将其设置为某个东西。

var myOutsideValue = 42,

    myFunction = function () {
        var myValue = 23;
        myOutsideValue = myValue;
    };



console.log(myOutsideValue); // 42
myFunction();
console.log(myOutsideValue); // 23

或者返回...

var myReturnedValue = 0,
    myFunction = function () {
        var myValue = 23;
        return myValue;
    };

myReturnedValue = myFunction();
console.log(myReturnedValue); // [log:] 23

或者你可以传入一个数组或对象来修改:

var myObject = {},

    myFunction = function (obj) {
        var myValue = 23;
        obj.value = myValue;
    };


myFunction(myObject);
console.log(myObject.value);  // [log:] 23

函数可以引用自己。
因为在 JavaScript 中,函数是对象(并且可以有自己的属性和方法),所以你可以像向任何{}对象添加属性一样向它们添加东西。

var myFunc = function () {
    var myValue = 23;
    myFunc.properties = {};
    myFunc.properties.value = myValue;
};


myFunc();
console.log(myFunc.properties.value); // [logs:] 23

这些都与this.

this用于与您要查找的内容相反的内容。
它适用于当您在附加到对象的函数内部,并且您想要读取其他属性/运行该对象上的其他方法时。

var myObject = {
    x : 23,
    y : 42,
    sayX : function () { console.log(this.x); },
    sayY : function () { console.log(this.y); }
};


myObject.sayX(); // [logs:] 23

this在其他几个地方使用,但实际上,这是它的主要作用:访问或设置函数附加到的对象上的值/方法(通过点属性访问obj.func(),或通过手动设置,使用.call/ .apply/ .bind),另一种非常常见的情况是使用new关键字创建新对象。

因此,让您x工作的方法不是弄清楚this,而是在函数本身内设置它,或者更恰当地,将x(返回x)传递给外部的另一个变量,然后自己设置值。

var foo = function () {
    var x = "x";
    return x;
},


variable;  // === undefined

foo.help = { o1 : 0 };

variable = foo(); // variable === "x"
foo.help.o1 = variable;


// or shorter:  foo.help.o1 = foo();

选择:

var help = { o1 : 0 },

    foo = function (obj) {
        var x = "x";
        obj.o1 = x;
    };



foo(help);
foo.help = help;

this仅在函数内部有效

var obj = {};

obj.x = 12;
obj.y = this.x + 5;  // DOESN'T WORK

如果this在最后一个示例中有效,那只是因为它是this从函数内部使用的,该函数将引用 FUNCTION'S this,而不是obj. 如果您正在调用未附加到对象(obj.func();func.call(obj)new_func = func.bind(obj);)的函数,this则将指向window.

于 2013-02-23T08:08:14.727 回答
0

在 context 中foo.help = {o1: x},您与 的定义不在同一个词法范围内x,后者将在foo函数范围内。这也适用于this.x(适用于对象范围)。

function foo() {
    var x = 5;
    this.help = x;
}
于 2013-02-23T07:12:50.133 回答