最近读了Javascript Enlightenment。总体感受仍是比较基础的。这里记录跟扩展下其中一些知识点。javascript
JS里有个不成文的规定,构造函数首字母大写。因此可能容易让人产生误解Math是构造函数。其实Math只是一个简单的封装了不少数学相关方法的对象。java
console.log(typeof Math); //"object"
console.log(typeof Array); //"function"复制代码
构造一个函数实例有2种方法:git
function sum(x, y) {
return x + y;
}
console.log(sum(3,4)); //7复制代码
let multiply = new Function("x", "y", "return x * y;");
console.log(multiply(3,4)); //12复制代码
工做中常常会有须要用到call或者apply来切换函数执行上下文的状况。例如:github
function print(){
console.log(this.a);
}
print.call({a: 'hello'}); //hello复制代码
有些面试题可能会问为啥print上没有定义call方法,可是print.call()调用为啥不会报错。实际上是由于print是Function的一个实例化对象,call方法定义在Function.prototype上,经过原型链查找到的call方法。面试
typeof能够用来判断基础类型,没法用typeof区分数组跟对象。数组
console.log(typeof [1,2]); //object
console.log(typeof {}); //object复制代码
能够有下面2种常见的方法区分数组:浏览器
console.log(Array.isArray([1,2])); //true复制代码
console.log(Object.prototype.toString.call([1,2])
.toLowerCase() === '[object array]'); //true复制代码
这里注意下,咱们使用了toString方法,而后用call方法切换toString调用时的上下文为咱们要进行判断的数组。因此有些人会误觉得Object.prototype.toString.call([1,2])跟 [1,2].toString()是等价的。其实否则:bash
console.log(Object.prototype.toString.call([1,2])); //[object Array]
console.log([1,2].toString()); //1,2复制代码
这是由于原型链查找有个就近原则。因此当使用[1,2].toString的时候,查找到并被使用的是Array.prototype.toString,这个方法覆盖了Object.prototype.toString。app
delete只会删除自身属性。不会删除原型链上的属性。函数
let obj = {a: 'self'};
Object.prototype.a = 'prototype';
console.log(obj.a); //self
delete obj.a;
console.log(obj.a); //prototype
delete Object.prototype.a;
console.log(obj.a); //undefined复制代码
访问全局对象有2种方法:
当咱们访问一个变量的时候会造成一个做用域链。做用域的顶端就是全局变量(i.e. 全局对象下的对应变量)。相对应的咱们也有全局函数和全局属性。曾经有一段代码坑了我下:
console.log(hasOwnProperty); //ƒ hasOwnProperty() { [native code] }复制代码
刚开始我觉得输出应该是undefined由于印象中hasOwnProperty并不是是全局函数。经过下面的例子你们能够想下为何hasOwnProperty不是全局函数可是上面的输出不是undefined ~
Object.prototype.hasOwnProperty.call(window, 'encodeURI'); // true
'hasOwnProperty' in window //true
Object.prototype.hasOwnProperty.call(window, 'hasOwnProperty'); // false复制代码
undefined表明没值。有2种状况可能出现没值。
let s;
console.log(s); //undefined复制代码
let obj1 = {};
console.log(obj1.a); //undefined复制代码
null表示有值,null是这个特殊的值。
let obj2 = {a: null};
console.log(obj2.a); //null复制代码
若是须要同时过滤undefined跟null的话,可使用弱等于检查。
console.log(null == undefined); //true
let arr = [null, undefined, 1];
let fil = arr.filter(it => {
return it != null;
});
console.log(fil); //[1]复制代码
另外undefined其实也是个全局变量, 可是null确不是。null也不挂载在window下。那么null是哪来的呢?
window.hasOwnProperty('undefined'); //true
window.hasOwnProperty('null'); //false
window.null //undefined复制代码