在创建 ._each 函数时如何编写 'context' 变量 (underscore.js)
How would you write the 'context' variable while creating the ._each function (underscore.js)
我正在尝试从 underscore.js 重新创建 _.each() 函数,但是无法使 'context' 变量正确。我明白它的意思,但似乎在绕圈子试图实施它。我已经用注释标记了下面的代码区域。任何提示表示赞赏,谢谢!
_.each = function (collection, iteratee, context) {
//-----context--------
if (context) {
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee.call(context, collection[i], collection);
}
} else {
for (const key in collection) {
iteratee.call(context, collection[key], collection);
}
}
return collection;
}
//-----end of context----
//check if array or object
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection);
}
} else {
for (const key in collection) {
iteratee(collection[key], key, collection);
}
}
return collection;
};
_.each(
[1, 2, 3],
function(value){
// get context by this
console.log(this.times * value);
},
{ times: 10 } // iteratee context,
)
您根本不需要 if (context) {
。从根本上讲,无论是否提供上下文,您都需要进行相同的操作,因此您可以将代码留在if
之外,并始终执行.call(context, /* other arguments */
。 Function#call
will always execute the function and the first parameter will be the this
value of that invocation. If the value undefined
is provided, then that's not an error - in non-strict mode the value of this
will be assigned to the global object but in strict
mode it How does the "this" keyword work?
因此,如果未提供上下文,那么您通常无需执行任何特殊操作。
const _ = {};
_.each = function (collection, iteratee, context) {
//check if array or object
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee.call(context, collection[i], collection);;
}
} else {
for (const key in collection) {
iteratee.call(context, collection[key], collection);
}
}
return collection;
};
const arr = [1, 2, 3];
const obj = {
foo: "hello",
bar: "world"
};
function print(value) {
console.log(value);
}
console.log("--- basic foreach ---");
_.each(arr, print);
_.each(obj, print);
console.log("--- foreach with context ---");
function contextPrint(value) {
console.log(this[value]);
}
_.each(arr, contextPrint, { 1: "one", 2: "two", 3: "three" });
_.each(obj, contextPrint, { hello: "this", world: "works" });
console.log("--- no context provided ---");
_.each(arr, contextPrint);
_.each(obj, contextPrint);
与 Underscore 比较,行为相同:
const arr = [1, 2, 3];
const obj = {
foo: "hello",
bar: "world"
};
function print(value) {
console.log(value);
}
console.log("--- basic foreach ---");
_.each(arr, print);
_.each(obj, print);
console.log("--- foreach with context ---");
function contextPrint(value) {
console.log(this[value]);
}
_.each(arr, contextPrint, { 1: "one", 2: "two", 3: "three" });
_.each(obj, contextPrint, { hello: "this", world: "works" });
console.log("--- no context provided ---");
_.each(arr, contextPrint);
_.each(obj, contextPrint);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js" integrity="sha512-wBiNJt1JXeA/ra9F8K2jyO4Bnxr0dRPsy7JaMqSlxqTjUGHe1Z+Fm5HMjCWqkIYvp/oCbdJEivZ5pLvAtK0csQ==" crossorigin="anonymous"></script>
我正在尝试从 underscore.js 重新创建 _.each() 函数,但是无法使 'context' 变量正确。我明白它的意思,但似乎在绕圈子试图实施它。我已经用注释标记了下面的代码区域。任何提示表示赞赏,谢谢!
_.each = function (collection, iteratee, context) {
//-----context--------
if (context) {
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee.call(context, collection[i], collection);
}
} else {
for (const key in collection) {
iteratee.call(context, collection[key], collection);
}
}
return collection;
}
//-----end of context----
//check if array or object
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection);
}
} else {
for (const key in collection) {
iteratee(collection[key], key, collection);
}
}
return collection;
};
_.each(
[1, 2, 3],
function(value){
// get context by this
console.log(this.times * value);
},
{ times: 10 } // iteratee context,
)
您根本不需要 if (context) {
。从根本上讲,无论是否提供上下文,您都需要进行相同的操作,因此您可以将代码留在if
之外,并始终执行.call(context, /* other arguments */
。 Function#call
will always execute the function and the first parameter will be the this
value of that invocation. If the value undefined
is provided, then that's not an error - in non-strict mode the value of this
will be assigned to the global object but in strict
mode it How does the "this" keyword work?
因此,如果未提供上下文,那么您通常无需执行任何特殊操作。
const _ = {};
_.each = function (collection, iteratee, context) {
//check if array or object
if (Array.isArray(collection)) {
for (let i = 0; i < collection.length; i++) {
iteratee.call(context, collection[i], collection);;
}
} else {
for (const key in collection) {
iteratee.call(context, collection[key], collection);
}
}
return collection;
};
const arr = [1, 2, 3];
const obj = {
foo: "hello",
bar: "world"
};
function print(value) {
console.log(value);
}
console.log("--- basic foreach ---");
_.each(arr, print);
_.each(obj, print);
console.log("--- foreach with context ---");
function contextPrint(value) {
console.log(this[value]);
}
_.each(arr, contextPrint, { 1: "one", 2: "two", 3: "three" });
_.each(obj, contextPrint, { hello: "this", world: "works" });
console.log("--- no context provided ---");
_.each(arr, contextPrint);
_.each(obj, contextPrint);
与 Underscore 比较,行为相同:
const arr = [1, 2, 3];
const obj = {
foo: "hello",
bar: "world"
};
function print(value) {
console.log(value);
}
console.log("--- basic foreach ---");
_.each(arr, print);
_.each(obj, print);
console.log("--- foreach with context ---");
function contextPrint(value) {
console.log(this[value]);
}
_.each(arr, contextPrint, { 1: "one", 2: "two", 3: "three" });
_.each(obj, contextPrint, { hello: "this", world: "works" });
console.log("--- no context provided ---");
_.each(arr, contextPrint);
_.each(obj, contextPrint);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js" integrity="sha512-wBiNJt1JXeA/ra9F8K2jyO4Bnxr0dRPsy7JaMqSlxqTjUGHe1Z+Fm5HMjCWqkIYvp/oCbdJEivZ5pLvAtK0csQ==" crossorigin="anonymous"></script>