1.null和undefined的区别
javaScript权威指南: null 和 undefined 都表示“值的空缺”,你可以认为undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。
javaScript高级程序设计: 在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。 null值则是表示空对象指针。
Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。
Null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象(如Object.prototype.__proto__
)。
- alert(null == document.getElementById('notExistElement'));
当页面上不存在id为"notExistElement"的DOM节点时,这段代码显示为"true",因为我们尝试获取一个不存在的对象。
- alert(typeof undefined); //output "undefined"
- alert(typeof null); //output "object"
第一行代码很容易理解,undefined的类型为Undefined;第二行代码却让人疑惑,为什么null的类型又是Object了呢?其实这是JavaScript最初实现的一个错误,后来被ECMAScript沿用下来。在今天我们可以解释为,null即是一个不存在的对象的占位符,但是在实际编码时还是要注意这一特性。
- alert(null == undefined); //output "true"
ECMAScript认为undefined是从null派生出来的,所以把它们定义为相等的。但是,如果在一些情况下,我们一定要区分这两个值,那应该怎么办呢?可以使用下面的两种方法。
- alert(null === undefined); //output "false"
- alert(typeof null == typeof undefined); //output "false"
使用typeof方法在前面已经讲过,null与undefined的类型是不一样的,所以输出"false"。而===代表绝对等于,在这里null === undefined输出false。
2.ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种基本数据类型;
3.Function.__proto__ === Function.prototype;
4.this指向问题
- 箭头函数中没有
this
绑定,this
的值取决于其创建时所在词法环境链中最近的this
绑定 - 非严格模式下,函数普通调用,
this
指向全局对象 - 严格模式下,函数普通调用,
this
为undefined
- 函数作为对象方法调用,
this
指向该对象 - 函数作为构造函数配合
new
调用,this
指向构造出的新对象 - 非严格模式下,函数通过
call
、apply
、bind
等间接调用,this
指向传入的第一个参数这里注意两点:
bind
返回一个函数,需要手动调用,call
、apply
会自动调用- 传入的第一个参数若为
undefined
或null
,this
指向全局对象
- 严格模式下函数通过
call
、apply
、bind
等间接调用,this
严格指向传入的第一个参数;
5.js数组方法:
- map(映射):原数组被映射成新的数组。
var arrNew = array.map(callback,[thisObject]);
array.map(callback,[ thisObject]);
callback
的参数也类似:
[].map(function(value, index, array) { // ... });
callback中需要return,不然新数组为相应的undefined组成的数组。
- filter对数组中的每个元素都执行一次指定的函数(callback),并且创建一个新的数组,该数组元素是所有回调函数执行时返回值为 true 的原数组元素。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略,同时,新创建的数组也不会包含这些元素。
- some 对数组中的每个元素都执行一次指定的函数(callback),直到此函数返回 true,如果发现这个元素,some 将返回 true,如果回调函数对每个元素执行后都返回 false ,some 将返回 false。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略。
- every 与some相反,对数组中的每个元素都执行一次指定的函数(callback),直到此函数返回 false,如果发现这个元素,every 将返回 false,如果回调函数对每个元素执行后都返回 true ,every 将返回 true。它只对数组中的非空元素执行指定的函数,没有赋值或者已经删除的元素将被忽略
- forEach没有返回值,对数组里的单个元素操作
- 综上,map,filter返回一个新数组,some,every返回true或false,forEach没有返回值。
6.DOM文档加载步骤:
1.解析HTML结构
2.加载外部的脚本和样式文件
3.解析并执行脚本代码
4.执行$(function(){})
内对应代码
5.加载图片等二进制资源
6.页面加载完毕,执行window.onload
7.类数组转数组:
[].slice.call(arguments)
8.判断对象:
使用typeof不能准确判断一个对象变量,因为使用typeof,null和Array的结果都是Object,有时候我们需要的是 "纯粹" 的 object 对象,使用如下方式比较好:
Object.prototype.toString.call(obj) === "[object Object]"
console.log(Object.prototype.toString.call("jerry"));//[object String] console.log(Object.prototype.toString.call(12));//[object Number] console.log(Object.prototype.toString.call(true));//[object Boolean] console.log(Object.prototype.toString.call(undefined));//[object Undefined] console.log(Object.prototype.toString.call(null));//[object Null] console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object] console.log(Object.prototype.toString.call(function(){}));//[object Function] console.log(Object.prototype.toString.call([]));//[object Array] console.log(Object.prototype.toString.call(new Date));//[object Date] console.log(Object.prototype.toString.call(/d/));//[object RegExp] function Person(){}; console.log(Object.prototype.toString.call(new Person));//[object Object]
同样是检测对象obj调用toString方法(关于toString()方法的用法的可以参考toString的详解),obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?这是因为toString为Object的原型方法,而Array
,function等类型作为Object的实例,都重写了toString方法。