1.new操作符
先写一个链表节点的构造函数:
function ListNode(val){
this.val = val;
this.next = null;
}注意,为了区分构造函数与普通函数,构造函数名称首字母都是大写的。此时的this指向的是window对象,接下来我们对它进行实例化。
var list = new ListNode(1);此时的list就是ListNode这个构造函数的一个实例,此时构造函数中的this指向它的调用者,即list这个实例。我们在控制台输入:
list instanceof ListNode
//true
ListNode instanceof Function
//trueinstanceof这个方法可以用来判断某个对象是否是某个构造函数的实例,当然,我们还可以用===来判断:
list.__proto__ === ListNode.prototype
//true
ListNode.__proto__ === Function.prototype
//true
Function.prototype.__proto__ === Object.prototype
//true.__proto__这个操作符说通俗一点就是以什么什么为原型,上面三条代码的意思依次是:
1.实例化对象list以ListNode上的prototype属性为原型,ListNode.prototype可以理解为指向一个几乎为空的对象,里面constructor指向ListNode函数本身
2.构造函数ListNode以Function.prototype为原型
3.Function.prototype以Object.prototype为原型
(注意,函数具有prototype属性,我们一般只关心构造函数的prototype属性)
注意,所有引用类型的最终原型都会是Object.prototype,我们来试验一下
ListNode instanceof Object
//true结合上面两段代码来看,ListNode这个构造函数的直接原型是Function.prototype,而Function.prototype的原型就是Object.prototype,instaceof这个函数会沿着你的原型链上去找,一开始只找到了Function.prototype,然后沿着Function.prototype往上找,最终找到了Object.prototype,返回true。是不是感觉跟闭包往上找变量有点相似?
再来举个数组的例子,帮助理解:
[] instanceof Array
//true
[] instanceof Object
//true数组的直接原型是Array.prototype,而Array.prototype又是以Object.prototype为原型的。
那Object.prototype的原型是啥呢?为null。
Object.prototype.__proto__ === null
//true