方法(对象的函数)可以使用“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)
我的理解: 范围是一个带变量from和to的函数。 Range.methods是Range的属性。它在Range()之外定义,但它仍然可以访问和使用(使用this.from和this.to)。怎么样? 谢谢。
答案 0 :(得分: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
示例中的methods
上的range
不是该功能的一部分
它们是 赋予对象的方法,因为它们是构造的 。
在您给出的示例中,这发生在r = inherit(range.methods);
调用内部,该代码块中未对此进行解释。
this
根本没有提到这个功能
它指的是 最终对象,该方法在调用方法时使用方法 。
我的range_3_to_5
和range_6_to_12
都使用includes
的相同副本
调用range_3_to_5.includes(6);
后,this
设置为range_3_to_5
,然后该函数会使用this.from
和this.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
但是如果你想让你的变量存在于函数的OUTSIDE(而不是更深入的内部),那么你需要将值返回到某个东西,或者直接从函数内部将它设置为某个东西。
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
功能 CAN 引用自己。
因为在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
用于其他几个方面,但实际上,这是它的主要作用:访问或设置附加函数的对象的值/方法(通过点属性访问{{1或者通过手动设置,使用obj.func()
/ .call
/ .apply
),其他非常常见的情况是使用.bind
关键字创建新对象。
因此,让new
工作的方法并不是弄清x
,而是将其设置在函数内部,或者更合适地通过this
out(返回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
,而是指向FUNCTION'S this
,而不是this
}。如果您正在调用未附加到对象(obj
或obj.func();
或func.call(obj)
)的函数,则new_func = func.bind(obj);
将指向this
答案 1 :(得分:0)
在上下文foo.help = {o1: x}
中,您与x
的定义不在同一个词法范围内,foo
定义在this.x
函数范围内。这也适用于function foo() {
var x = 5;
this.help = x;
}
(适用于对象范围)。
{{1}}