5条原型规则所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了"null")以外所有的引用类型(数组、对象、函数),都有一个__proto__ (隐式原型)属性,属性值是一个普通的对象所有的函数,都有一个 prototype (显式原型)属性,属性值也是一个普通的对象所有的引用类型(数组、对象、函数),proto 属性值指向它的构造函数的 prototype 属性值当试图得到一个对象(引用类型)的某个属性时,如果这个对象本身没有这个属性,那么会去它的 proto(即它的构造函数的 prototype)中寻找var obj = {};obj.a = 100;var arr = [];arr.a = 100;function fn () {}fn.a = 100;console.log(obj.proto); // Objectconsole.log(arr.proto); // Arrayconsole.log(fn.proto); // ƒ () { [native code] }console.log(fn.prototype); // Objectconsole.log(obj.proto === Object.prototype); // true如何准确判断一个变量是数组类型?var arr = [];arr instanceof Array // truetypeof arr // object typeof无法判断是否是数组一个原型链继承的例子function Elem(id) { this.elem = document.getElementById(id);}Elem.prototype.html = function (val) { var elem = this.elem; if (val) { elem.innerHTML = val; return this; // 链式调用 } else { return elem.innerHTML; }};Elem.prototype.on = function (type, fn) { var elem = this.elem; elem.addEventListener(type, fn); return this;};var div1 = new Elem(‘articleTitle’);console.log(div1.html());div1.html(’<p>hello gril~</p>’);div1.on(‘click’, function () { alert(‘clicked!’);});div1.html(’<p>hello gril~</p>’).on(‘click’, function () { alert(‘clicked!’);}).html(’<p>Nice to meet you.</p>’);描述 new 一个对象的过程创建一个新对象this指向这个新对象执行代码,即对this赋值返回thisfunction Foo (name, age) { // 首先this变成空对象 this.name = name; this.age = age; this.class = ‘class-1’; // return this; // 默认有这一行}var f = new Foo(’li’, 20);var f1 = new Foo(‘wang’, 22); // 创建多个对象构造函数function Foo (name, age) { this.name = name;}Foo.prototype.getName = function () { console.log(this.name);};// 创建实例var f = new Foo(‘can’);f.printName = function () { console.log(this.name);};// 测试f.printName();f.getName();f.toString(); // 要去 f.proto.proto 中查找for (var key in f) { // 我们希望循环得到的是对象本身的属性,而不希望得到来自原型的属性 // 高级浏览器已经在 for in 中屏蔽了来自原型的属性 // 但是建议还是加上这个判断,保证程序的健壮性 if (f.hasOwnProperty(key)) { console.log(key); // name printName }}instanceof 用于判断引用类型属于哪个构造函数的方法f instanceof Foo 的判断逻辑是:f 的__proto__ 一层一层往上,是否对应到Foo.prototype,再试着判断 f instanceof Object