在本文中,我们将为您详细介绍javascript–方法Set.prototype.add调用不兼容的接收器undefined的相关知识,并且为您解答关于js无法调用的疑问,此外,我们还会提供一些关于A
在本文中,我们将为您详细介绍javascript – 方法Set.prototype.add调用不兼容的接收器undefined的相关知识,并且为您解答关于js无法调用的疑问,此外,我们还会提供一些关于Array.prototype.find()、Array.prototype.findIndex()、Array.prototype.keys()、Array.prototype.values()和Array.prototype.entries()、Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)、Array.prototype.toString()和Array.prototype.toLocaleString()的有用信息。
本文目录一览:- javascript – 方法Set.prototype.add调用不兼容的接收器undefined(js无法调用)
- Array.prototype.find()、Array.prototype.findIndex()
- Array.prototype.keys()、Array.prototype.values()和Array.prototype.entries()
- Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)
- Array.prototype.toString()和Array.prototype.toLocaleString()
javascript – 方法Set.prototype.add调用不兼容的接收器undefined(js无法调用)
这是我在chrome控制台上测试的内容:
> var mySet; <- undefined > mySet = new Set; <- Set {} > mySet.add('foo','bar','baz') // Worked as expected <- Set {"foo"} // just the first argument was added > ['bar','baz'].forEach(mySet.add) X-> VM1529:1 Uncaught TypeError: Method Set.prototype.add called on incompatible receiver undefined(…)
提前致谢.
解决方法
['bar','baz'].forEach(mySet.add.bind(mySet))
Array.prototype.find()、Array.prototype.findIndex()
arr.find(callback[, thisArg])
var inventory = [
{name: ''apples'', quantity: 2},
{name: ''bananas'', quantity: 0},
{name: ''cherries'', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === ''cherries'';
}
console.log(inventory.find(findCherries)); // { name: ''cherries'', quantity: 5 }
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime)); // undefined, not found
console.log([4, 5, 8, 12].find(isPrime)); // 5
// Declare array with no element at index 2, 3 and 4
var a = [0,1,,,,5,6];
// Shows all indexes, not just those that have been assigned values
a.find(function(value, index) {
console.log(''Visited index '' + index + '' with value '' + value);
});
// Shows all indexes, including deleted
a.find(function(value, index) {
// Delete element 5 on first iteration
if (index == 0) {
console.log(''Deleting a[5] with value '' + a[5]);
delete a[5]; // 注:这里只是将a[5]设置为undefined,可以试试用a.pop()删除最后一项,依然会遍历到被删的那一项
}
// Element 5 is still visited even though deleted
console.log(''Visited index '' + index + '' with value '' + value);
});
polyfill
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, ''find'', {
value: function(predicate) {//遍历的处理函数
// 1. Let O be ? ToObject(this value).
if (this == null) {//数组为null
throw new TypeError(''"this" is null or not defined'');
}
var o = Object(this);//数组
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;//数组长度
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== ''function'') {//第一个参数必须是函数
throw new TypeError(''predicate must be a function'');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];//第二个参数指定this
// 5. Let k be 0.
var k = 0;//遍历索引
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {//如果当前值经过处理函数后返回了true,就返回当前值
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;//未找到就返回undefined
}
});
}
Array.prototype.findIndex()
此方法是 ES6 方法。
此方法不改变原数组。
polyfill
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex
if (!Array.prototype.findIndex) {
Object.defineProperty(Array.prototype, ''findIndex'', {
value: function(predicate) {//第一个参数处理函数
// 1. Let O be ? ToObject(this value).
if (this == null) {//数组为null抛错误
throw new TypeError(''"this" is null or not defined'');
}
var o = Object(this);//数组
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;//数组长度
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== ''function'') {//第一个参数不是函数抛错误
throw new TypeError(''predicate must be a function'');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];//第二个参数是指定this值
// 5. Let k be 0.
var k = 0;//遍历索引
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return k.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {//如果当前值符合要求就返回当前值的索引
return k;
}
// e. Increase k by 1.
k++;
}
// 7. Return -1.
return -1;//找不到符合要求的值就返回-1
}
});
}
Array.prototype.keys()、Array.prototype.values()和Array.prototype.entries()
Array.prototype.keys()
keys() 方法返回一个包含数组中每个索引键的Array Iterator对象。
var arr = ["a", , "c"];
var sparseKeys = Object.keys(arr);
var denseKeys = [...arr.keys()];
console.log(sparseKeys); // [''0'', ''2'']
console.log(denseKeys); // [0, 1, 2]
Array.prototype.values()
values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值
此方法不会改变数组。
let arr = [''w'', ''y'', ''k'', ''o'', ''p''];
let eArr = arr.values();
// 您的浏览器必须支持 for..of 循环
// 以及 let —— 将变量作用域限定在 for 循环中
for (let letter of eArr) {
console.log(letter);
}
另一种迭代方式
let arr = [''w'', ''y'', ''k'', ''o'', ''p''];
let eArr = arr.values();
console.log(eArr.next().value); // w
console.log(eArr.next().value); // y
console.log(eArr.next().value); // k
console.log(eArr.next().value); // o
console.log(eArr.next().value); // p
Array.prototype.entries()
entries() 方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
var arr = ["a", "b", "c"];
var iterator = arr.entries();
// undefined
for (let e of iterator) {
console.log(e);
}
// [0, "a"]
// [1, "b"]
// [2, "c"]
Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)
Array.prototype.push.apply(a,b)
时常看到在操作数组的时候有这样的写法:
var a = [1,2,3];
var b = [4,5,6];
a.push.apply(a, b);
console.log(a) //[1,2,3,4,5,6]
其实这样的写法等价于:
var a = [1,2,3];
var b = [4,5,6];
Array.prototype.push.apply(a, b);
console.log(a) //[1,2,3,4,5,6]
这样写法等价的原因是因为在实例上寻找属性的时候,现在这个实例自己身上找,如果找不到,就根据内部指针__proto__随着原型链往上找,直到找到这个属性。
在这里就是寻找push方法,两种写法最后找到的都是Array构造函数对应的prototype的原生方法push。所以说两种写法是等价的。
但是为什么要使用a.push.apply(a,b);这种写法呢?为什么不直接使用push()?
如果直接push:
var a = [1,2,3];
var b = [4,5,6];
a.push(b);
console.log(a) //[1, 2, 3, Array(3)]
这样就看出来区别了,原生push方法接受的参数是一个参数列表,它不会自动把数组扩展成参数列表,使用apply的写法可以将数组型参数扩展成参数列表,这样合并两个数组就可以直接传数组参数了。
但是合并数组为什么不直接使用Array.prototype.concat()呢?
因为concat不会改变原数组,concat会返回新数组,而上面apply这种写法直接改变数组a。
同理,Math.max和Math.min也可以使用apply这种写法来传入数组参数。
比如这样:
Math.max.apply(null,a)
这样就可以很方便的传入数组参数了。
Array.prototype.slice.call(arguments)
类似的还有这样的写法,MDN解释slice方法可以用来将一个类数组(Array-like)对象/集合转换成一个新数组。你只需将该方法绑定到这个对象上。
所以可以使用slice将函数的参数变成一个数组,然后就可以当做数组来操作了。
Object.prototype.hasOwnProperty.call(object,prop)
类似还有这样的写法,这样写是因为js没有保护hasOwnProperty 属性名,hasOwnProperty 有可能被修改为其他方法,所以这样写可以调用到原生的Objext原型上的hasOwnProperty 方法。这样写等价于({}).hasOwnProperty.call(object,prop)
Object.prototype.toString.call()
这样的写法是为了判断一个变量是什么类型的数据:
var toString = Object.prototype.toString;
toString.call(123); //"[object Number]"
toString.call(''abcdef''); //"[object String]"
toString.call(true); //"[object Boolean]"
toString.call([1, 2, 3, 4]); //"[object Array]"
toString.call({name:''wenzi'', age:25}); //"[object Object]"
toString.call(function(){ console.log(''this is function''); }); //"[object Function]"
toString.call(undefined); //"[object Undefined]"
toString.call(null); //"[object Null]"
toString.call(new Date()); //"[object Date]"
toString.call(/^[a-zA-Z]{5,20}$/); //"[object RegExp]"
toString.call(new Error()); //"[object Error]"
使用Object.prototype.toString.call()的方式来判断一个变量的类型是最准确的方法。
Array.prototype.toString()和Array.prototype.toLocaleString()
Array.prototype.toString()
toString() 返回一个字符串,表示指定的数组及其元素。
var monthNames = [''Jan'', ''Feb'', ''Mar'', ''Apr''];
var myVar = monthNames.toString(); // assigns "Jan,Feb,Mar,Apr" to myVar.
var i = [1, 2, 3,[1, 2, 3, [1, 2, 3]]];
i.toString()
//"1,2,3,1,2,3,1,2,3"
其实toString()就是返回了String(this)
Array.prototype.toLocaleString()
var prices = [''¥7'', 500, 8123, 12];
prices.toLocaleString(''ja-JP'', { style: ''currency'', currency: ''JPY'' });
// "¥7,¥500,¥8,123,¥12"
// https://tc39.github.io/ecma402/#sup-array.prototype.tolocalestring
if (!Array.prototype.toLocaleString) {
Object.defineProperty(Array.prototype, ''toLocaleString'', {
value: function(locales, options) {
// 1. Let O be ? ToObject(this value).
if (this == null) {//空数组抛错误
throw new TypeError(''"this" is null or not defined'');
}
var a = Object(this);//转成对象
// 2. Let len be ? ToLength(? Get(A, "length")).
var len = a.length >>> 0;//数组长度
// 3. Let separator be the String value for the
// list-separator String appropriate for the
// host environment''s current locale (this is
// derived in an implementation-defined way).
// NOTE: In this case, we will use a comma
var separator = '','';//分隔符是逗号
// 4. If len is zero, return the empty String.
if (len === 0) {//如果长度为0,返回空字符串
return '''';
}
// 5. Let firstElement be ? Get(A, "0").
var firstElement = a[0];//第一个数组元素
// 6. If firstElement is undefined or null, then
// a.Let R be the empty String.
// 7. Else,
// a. Let R be ?
// ToString(?
// Invoke(
// firstElement,
// "toLocaleString",
// « locales, options »
// )
// )
var r = firstElement == null ?
'''' : firstElement.toLocaleString(locales, options);//判断第一个元素为空情况然后计算后赋值给r
// 8. Let k be 1.
var k = 1;
// 9. Repeat, while k < len
while (k < len) {//循环数组
// a. Let S be a String value produced by
// concatenating R and separator.
var s = r + separator;//分隔符
// b. Let nextElement be ? Get(A, ToString(k)).
var nextElement = a[k];//下一个字符
// c. If nextElement is undefined or null, then
// i. Let R be the empty String.
// d. Else,
// i. Let R be ?
// ToString(?
// Invoke(
// nextElement,
// "toLocaleString",
// « locales, options »
// )
// )
r = nextElement == null ?
'''' : nextElement.toLocaleString(locales, options);//下一个字符转换成字符串
// e. Let R be a String value produced by
// concatenating S and R.
r = s + r;
// f. Increase k by 1.
k++;
}
// 10. Return R.
return r;
}
});
}
今天关于javascript – 方法Set.prototype.add调用不兼容的接收器undefined和js无法调用的讲解已经结束,谢谢您的阅读,如果想了解更多关于Array.prototype.find()、Array.prototype.findIndex()、Array.prototype.keys()、Array.prototype.values()和Array.prototype.entries()、Array.prototype.push.apply(a,b)和Array.prototype.slice.call(arguments)、Array.prototype.toString()和Array.prototype.toLocaleString()的相关知识,请在本站搜索。
本文标签: