1.document.querySelectorAll赋给其它变量时, 为什么要.bind(document)?
阮一峰的博客提到$的替代方法:
var $ = document.querySelectorAll.bind(document);
回答(1):我的理解是this的指向问题。querySelectorAll是document下的一个方法,附值给select后,select已经是window下的一个属性,此时,this已经不再是document,而window下没有querySelectorAll方法,所以会报错;var select = document.querySelectorAll.bind(document),能保证调用select()时this永远指向document。
回答(2):这个问题其实和querySelectorAll没什么关系。document是类的一个实例,而querySelectorAll是原型链上的方法。类比到普通的类和原型方法就很好理解了吧。
通过实例来运行原型链上的方法时,解释器会自动将this指向那个实例,但是直接这样var select = document.querySelectorAll;,你的变量仅仅是指向了原型链上的那个函数,而没有绑定this指针,所以你才需要在外面手动绑定一下指针。
回答(3):因为document.querySelectorAll是通过document这个对象去调用querySelectorAll的时候,函数的环境变量里this会指向document,假设querySelectorAll含有this的操作的话,那么this就会指代document。
而当你执行var select = document.querySelectorAll; 的时候,select所得到的是querySelector这个引用,但是此时如果直接通过select去调用的话,也就是select('span'); ,由于select(querySelectorAll)直接调用的话,this会自动指向window,所以就会出错。
bind的作用是,创建一个新函数,称为绑定函数。当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数。
而这句话var $ = document.querySelectorAll.bind(document);的效果相当于下面的代码
var $ = function(document) {
return function() {
return document.querySelectorAll.call(document, arguments);
}
}
2.对Array.prototype.slice.call()方法的理解
在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢?
(1)slice() 方法可从已有的数组中返回选定的元素。
start:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。
end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。
返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。该方法并不会修改数组,而是返回一个子数组。
(2)call()和apply()方法都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apply和call方法的第一个参数都是特定的作用域第二个参数不同,apply第二个参数可以是Array的实例,也可以是arguments对象。call方法需要逐个列出需要传递的参数。
(3)arguments对象指数与数组类似(它并不是Array的实例),但是可以使用方括号语法访问每一个元素,使用length来确定传递进来多少个参数。
(4)Array.prototype.slice.call()可以理解为:改变数组的slice方法的作用域,在特定作用域中去调用slice方法,call()方法的第二个参数表示传递给slice的参数即截取数组的起始位置。
原理:
Array.prototype.slice.call(arguments)能将具有length属性的对象(key值为数字)转成数组。[]是Array的示例,所以可以直接使用[].slice()方法。
var obj = {0:'hello',1:'world',length:2};
console.log(Array.prototype.slice.call(obj,0));//["hello", "world"]
没有length属性的对象
var obj = {0:'hello',1:'world'};//没有length属性
console.log(Array.prototype.slice.call(obj,0));//[]
可以借用Array.prototype.slice方法的对象要满足一下两个条件:
- 对象本身要可以存取属性
- 对象的length属性可读写
3.在 JavaScript 中, true && expression 总是会评估为 expression ,而 false && expression 总是执行为 false 。
console.log(true && "expression")
console.log(false && "expression")
输出:
expression
false
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。