博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS面试
阅读量:6922 次
发布时间:2019-06-27

本文共 2468 字,大约阅读时间需要 8 分钟。

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")输出:expressionfalse

转载地址:http://lfujl.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
快速排序
查看>>
mysql查询时截取字符串
查看>>
java死锁和避免死锁
查看>>
仲裁流程系统开发杂记
查看>>
消息中间件基础介绍
查看>>
PMP——折旧法
查看>>
增加ad属性
查看>>
bootstrap大图轮播手机端不能手指滑动解决办法
查看>>
DNS服务器*****(二)
查看>>
tomcat在conf/Catalina/localhost目录下配置项目路径
查看>>
网络设备在网络环境中的应用
查看>>
ICN:SDN后的下一个热潮
查看>>
图解linux下top命令的使用
查看>>
Linux远程管理工具screen
查看>>
利用Server2008影卷复制功能快速恢复误删文件
查看>>
Android学习—动态布局方法总结
查看>>
需求与暗需求
查看>>
那些好用的小工具——Database Browser
查看>>
如何使用Rebase以及bind来重定位和绑定dll
查看>>