目录
1、Array-like数据转换为数组,常见的Array-like数据有nodelist,agruments,具有索引,长度属性的对象;
1、Array-like数据转换为数组,常见的Array-like数据有nodelist,agruments,具有索引,长度属性的对象;
- for循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
<script>
function toArray(arrayLike) {
var result = [];
if (Object.prototype.toString.call(arrayLike) === '[object Object]'){
for (var key in arrayLike) {
if (key !== 'length') {
result.push(arrayLike[key])
}
}
} else {
for (var i = 0, l = arrayLike.length; i < l; i++) {
result.push(arrayLike[i]);
}
}
return result;
}
/* nodelist */
var nodes = document.querySelectorAll('div');
toArray(nodes); // [div, div, div]
/* arguments */
function arg() {
toArray(arguments) // [1, 2, 3, 4]
}
arg(1, 2, 3, 4)
/* 具有长度和索引属性的对象 */
toArray({0: 'a', 1: 'b', 2: 'c', length: 3}) // ["a", "b", "c"]
</script>
2. Array.prototype.slice.call()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
<script>
function toArray(arrayLike) {
return Array.prototype.slice.call(arrayLike)
}
/* nodelist */
var nodes = document.querySelectorAll('div');
toArray(nodes); // [div, div, div]
/* arguments */
function arg() {
toArray(arguments) // [1, 2, 3, 4]
}
arg(1, 2, 3, 4)
/* 具有长度和索引属性的对象 */
toArray({0: 'a', 1: 'b', 2: 'c', length: 3}) // ["a", "b", "c"]
</script>
3.Array.from()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
<script>
function toArray(arrayLike) {
return Array.from(arrayLike)
}
/* nodelist */
var nodes = document.querySelectorAll('div');
toArray(nodes); // [div, div, div]
/* arguments */
function arg() {
toArray(arguments) // [1, 2, 3, 4]
}
arg(1, 2, 3, 4)
/* 具有长度和索引属性的对象 */
toArray({0: 'a', 1: 'b', 2: 'c', length: 3}) // ["a", "b", "c"]
</script>
4. Set,针对可迭代对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
<script>
function toArray(arrayLike) {
var result = new Set(arrayLike);
return [...result]
}
/* nodelist */
var nodes = document.querySelectorAll('div');
toArray(nodes); // [div, div, div]
/* arguments */
function arg() {
toArray(arguments) // [1, 2, 3, 4]
}
arg(1, 2, 3, 4)
/* 具有长度和索引属性的对象 */
toArray({0: 'a', 1: 'b', 2: 'c', length: 3}) // 报错,对象不是可迭代对象
</script>
2、类型判断
- typeof,主要用来检测基本类型,如
var type = {
str: '1',
num: 1,
bool: false,
undef: 'undefined',
nul: null,
symb: Symbol(),
func: console.log(),
regexp: /ab/i,
arr: [],
obj: {},
cons: new Array()
}
var res = []
Object.keys(type).forEach(key => {
/* typeof */
res.push(typeof type[key])
})
console.log(res) // ["string", "number", "boolean", "string", "object", "symbol", "undefined", "object", "object", "object", "object"]
2. instanceof ,用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
var simpleStr = "This is a simple string";
var myString = new String();
var newStr = new String("String created with constructor");
var myDate = new Date();
var myObj = {};
var myNonObj = Object.create(null);
simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined
myString instanceof String; // 返回 true
newStr instanceof String; // 返回 true
myString instanceof Object; // 返回 true
myObj instanceof Object; // 返回 true, 尽管原型没有定义
({}) instanceof Object; // 返回 true, 同上
myNonObj instanceof Object; // 返回 false, 一种创建对象的方法,这种方法创建的对象不是Object的一个实例
myString instanceof Date; //返回 false
myDate instanceof Date; // 返回 true
myDate instanceof Object; // 返回 true
myDate instanceof String; // 返回 false
3. Object.prototype.toString.call() ,除了以下的值,Object.prototype.toString.call()还可以检测arguments,nodelist等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
<script>
var type = {
str: '1',
num: 1,
bool: false,
undef: 'undefined',
nul: null,
symb: Symbol(),
func: console.log(),
regexp: /ab/i,
arr: [],
obj: {},
}
var res = []
Object.keys(type).forEach(key => {
/* typeof */
res.push(Object.prototype.toString.call(type[key]))
})
console.log(res) // ["[object String]", "[object Number]", "[object Boolean]", "[object String]",
// "[object Null]", "[object Symbol]", "[object Undefined]", "[object RegExp]", "[object Array]", "[object Object]"]
</script>
3.call,apply,bind源码实现
1.bind源码实现
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
// this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
return fToBind.apply(this instanceof fBound
? this
: oThis,
// 获取调用时(fBound)的传参.bind 返回的函数入参往往是这么传递的
aArgs.concat(Array.prototype.slice.call(arguments)));
};
// 维护原型关系
if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
// 下行的代码使fBound.prototype是fNOP的实例,因此
// 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype = new fNOP();
return fBound;
};
}
2. call源码实现
if (!Function.prototype.call) {
Function.prototype.call = function (context) {
var content = context || window;
content.fn = this;
var args = [];
// arguments是类数组对象,遍历之前需要保存长度,过滤出第一个传参
for (var i = 1, len = arguments.length ; i < len; i++) {
// 避免object之类传入
args.push(arguments[i]);
}
/*var result = eval('content.fn('+args+')');
delete content.fn;*/
var result = context.fn(...args)
delete context.fn
return result;
}
}
3.apply源码实现
if (!Function.prototype.apply) {
Function.prototype.apply = function (context) {
var content = context || window;
content.fn = this;
var args = arguments[1]
if (!args) {
context.fn()
} else {
/*var result = eval('content.fn('+args+')');
delete content.fn;*/
var result = context.fn(...args)
}
delete context.fn
return result;
}
}