关于js的一些被忽视但也很重要的知识点
以为懂了,实际没懂。对新知识保持好奇心很有必要,但对原有知识也要更深入了解其细节。温故知新,“新”,应该是自己不懂的,亦或是遗忘了的,亦或是......
问题1:
Object.prototype.toString.call([])
的结果是"[object Array]"
,为什么和[].toString()
的结果""
不一致?按理说,结果应该是一样的。
先来说说Object.prototype.toString.call([])
,这个技巧常用来区分某个变量值是Object
、Array
哪一种数据类型(因为此时 typeof 排不上用场了)。
typeof []; // "object"
typeof {}; // "object"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"
结果不一致的原因,查阅了 MDN ,是这么描述的:
- 每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。
- Array对象覆盖了Object的 toString 方法。对于数组对象,toString 方法连接数组并返回一个字符串,其中包含用逗号分隔的每个数组元素。
扩展:
- 还有什么方法能区分
Object
、Array
?答案:ES5提供的Array.isArray()
。
Array.isArray([]); // true
Array.isArray({}); // false
-
如何记忆
Object.prototype.toString.call()
和Object.prototype.toString.apply()
这两个的第二个参数,总是记不清,哪个该传数组?答案:
apply
是以字母a
开头的,联想到array
,就知道它该传递数组作为参数了,是不是很容易就记住了。ps:关于记忆知识的小窍门,欢迎留言,看看谁的小窍门更容易让人记住~~。
问题来源:同事提问。交流也是学习的一种途径。
问题2:
请准确说出以下表达式的结果及数据类型。
'1,2,3,4'.split();
'112211331144'.split('11', 2);
答案:
'1,2,3,4'.split(); // ["1,2,3,4"]
'112211331144'.split('11', 2); // ["", "22"]
关键点:
- 语法:
str.split([separator[, limit]])
- 返回值是一个字符串数组 arr。
- 参数值均为可选
- separator:分隔符,若不传,返回
[原始字符串]
。之前一直以为默认 逗号 分隔呢,不记得是在哪记忆的了。感觉像小 海伦凯勒“看了”或“听了”很多书,怀疑自己的思想或想法是不是从其他地方学来的。 - limit:限制返回值 arr 个数,若不传,默认没有限制,即返回所有值;若 limit < arr.length,则 arr.length = limit;若 limit > arr.length,则结果如同没传。
- separator:分隔符,若不传,返回
可参考:MDN 上关于 String.prototype.split 的描述
问题来源:看文档。
问题3:
请准确说出以下表达式的结果及数据类型。
var str = 'aabbccdd';
str.substring(4,0);
str.substring(4,NaN);
str.substring(-4,10);
答案:
str.substring(4,0); // "aabb" 等同于 str.substring(0,4)
str.substring(4,NaN); // "aabb" 等同于 str.substring(4,0)
str.substring(-4,10); // "aabbccdd" 等同于 str.substring(0)
关键点:
- 语法:
str.substring([indexStart[,indexEnd]])
- 参数均可不传
- indexStart,不传为 0;
- indexEnd,不传为 str.length;
- 任一参数,小于 0 或 为 NaN, 则视为 0
- 任一参数,大于 str.length, 则视为 str.length
- indexStart > indexEnd,结果如同参数调换的结果。
可参考:MDN 上关于 String.prototype.substring 的描述
问题来源:看文档。
问题4:
- a 标签的 href 和 onclick 属性同时存在时哪个先触发?
- 对于
<a href="#">点击</a>
点击了有什么表现? - a标签下的
href="javascript:void(0)"
起到了什么作用? - a标签属性
rel='nofollow'
有什么作用?
答案(自己写demo可验证):
- a 标签的 href 会先触发。
<a href="#">点击</a>
,点击了href="#top"
或者href="#"
链接会返回到页面顶部(h5新特性)。- 备注:若页面中有标签且id值为top,点击
href="#top"
的 a 标签,不会返回到页面顶部,而是返回到 id 值为 top 的地方(锚点的特性)。
- 备注:若页面中有标签且id值为top,点击
- 表现形式,具有 a 标签的链接样式,但不具备 a 标签的链接跳转功能或刷新页面。建议用 button 替换此类伪链接。若要执行实际,建议添加点击事件触发。
void 表达式
返回undefined
,通常用来创建正确的undefined
,因为undefined
可被赋值修改。- 当点击一个
javascript: URI
时,会执行 URI 中的代码,返回值替换页面内容,除非返回值为 undefined。 - 可测试一下代码查看
<a href="javascript:0">整个页面会被替换成一个字符 0 (ie9改变,chrome不变)</a> <a href="javascript:void(document.body.style.backgroundColor='skyblue')">页面背景为蓝色,内容不变(返回值为 undefined)</a> <a href="javascript:jsfn()">调用jsfn,(ie9内容改变,chrome内容不变,背景色改变)</a> <script> function jsfn() { document.body.style.backgroundColor='orangered'; return 11 } </script>
- rel 属性值:
- 'nofollow':和 SEO 有关,爬虫遇到链接,默认爬取链接内容,加了该属性值就不爬取该链接的内容。
- 'prefetch'、'preload':和资源加载有关,prefetch 空闲加载,repload 立即加载。
- 'noopener'、'noreferrer':和安全有关,控制跳转到其他页面发送的安全信息,比如http头、页面名字等。
可参考:
问题来源:代码中经常写,但不理解。理解不理解的代码也是一种学习途径,就好比弄懂不知道的英文单词一样。
备注:这些点看似很小,可能平常根本不关注,但遇到了,就是一个坑。懂原理能少走一些弯路。后续遇到了再补充。