每个js对象包含一个__proto__指向他的原型,而这个实例对象的构造函数呢有个prototype->当前原型,所以实例对象.proto === 构造函数.prototype
这还是第一层 上面的原型的__proto__指向object,object.__proto__指向null
···
//1. 构造函数 缺点 使用typeof判断对象时返回object 必须使用instanceof来判断是哪个对象
function Person(){};
var p1 = new Person();
//2. 字面量 批量实例对象麻烦
var p1 = {}
//3. 工厂函数 批量设置对象
function CreatePerson(){ var obj = new Obj();}
···
var father = {name="parent"};
var son = {name="son",age="18"};
function extend(father , son){
for(var key in parent){
if(child[key]){continue;}
child[key] = parent[key];
}
}
//1. 原型链继承 缺点: 由于new Person 只能调用一次 不能为父类传值
function Person(name){
this.name = name;
}
Student.prototype = new Person();
Student.prototype.constructor=Student;
function Student(level){
this.level= level
}
var s1 = new Student("class2");
// 2. 借用构造函数 缺点: 无法继承父类的原型方法 如果方法写入Person构造函数那么每个student继承都会有个方法
function Person(name){
this.name = name;
}
function Student(name, level){
Person.call(this, name);
this.level= level
}
var s1 = new Student("mike","class2");
var s2 = new Student("mike2","class3");
// 3. 组合继承 通过2次实例化父类 实现继承属性、方法; 缺点: 消耗内存 子类屏蔽一次父类实例化对象
function Person(name){
this.name = name;
}
Person.prototype.sayName=function(){console.log(this.name)}
Student.prototype = new Person();
Student.prototype.constructor=Student;
function Student(name,level){
Person.call(this, name);
this.level = level;
}
var s1 = new Student("mike","class2");
//4.【完美方案】使用一个空对象去接父类原型, 减小内存开销
function Person(name){
this.name = name;
}
Person.prototype.sayName=function(){console.log(this.name)}
function Student(name,level){
Person.call(this, name);
this.level = level;
}
(function(){
var tmp = function() {};
tmp .prototype = Person.prototype;
Student.prototype = new tmp ();
Student.prototype.constructor = Student;
})()
var s1 = new Student("mike","class2");
//格式
(function(window,undefined){})(window,undefined);
//使用原因: 便于压缩、避免undefined被修改
//1. fn()
//2. .call(this, 参数...)
//3. new Function(‘参数1’,'函数体')()
//4. var xxx = function(){} 函数表达式
var a = fn();//aaa fn申明提升到最前面
function fn(){console.log('aaa')};
b();//错误 函数表达式不提升
var b = function(){console.log('bbb')};
// 具体一个应用 为伪数组借用数组的方法
var obj = {0:0;1:1}
// 但是没有插入的数组方法
Array.prototype.toString.call(obj, 2)
// 原本定时器的this都是window 但是现在改为xxx
setInterval(function(){}.bind(xxx),1000)
// Math.max用于数字 但是 使用 apply改造给数组
arr = [1 ,2 ,3]
Math.max.apply(null,arr);
// null是this这里不改写null
就是 1. 函数做参数 2. 函数作为返回值
// 例子
arr.sort(function(a,b){return a-b})//小到大 b-a 大到小
一个作用域 获得 另一个作用域的内容
首先 一下不是闭包
function fn(){var a = 0; return a}
fn()
真正的闭包
function fn(){var a= 0; return function(){return a}};
fn();
闭包可以延展作用域 方便数据使用 但是 会造成内存常驻 导致性能下降
闭包应用 为每个btn 绑定点击事件 返回对应的索引
var btnArr = document.getElementsByTagName('button');
for(var i = 0; i<3; i++){
btnArr[i].onclick = (function(i){console.log(i)})(i);
}
// 0 1 2