JS高级知识点总结

1.原型链

每个js对象包含一个__proto__指向他的原型,而这个实例对象的构造函数呢有个prototype->当前原型,所以实例对象.proto === 构造函数.prototype

这还是第一层 上面的原型的__proto__指向object,object.__proto__指向null

2. 实例化对象3方法

···
//1. 构造函数 缺点 使用typeof判断对象时返回object 必须使用instanceof来判断是哪个对象
function Person(){};
var p1 = new Person();
//2. 字面量 批量实例对象麻烦
var p1 = {}
//3. 工厂函数 批量设置对象
function CreatePerson(){ var obj = new Obj();}
···

3.对象拷贝

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];
	}
}

4.继承

//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");

5.自调用函数

//格式
(function(window,undefined){})(window,undefined);
//使用原因: 便于压缩、避免undefined被修改

6.函数申明方式

//1. fn()
//2. .call(this, 参数...)
//3. new Function(‘参数1’,'函数体')()
//4. var xxx = function(){} 函数表达式

7.申明提升

var a = fn();//aaa fn申明提升到最前面
function fn(){console.log('aaa')};
b();//错误 函数表达式不提升
var b = function(){console.log('bbb')};

8. call、bind、apply区别

  1. call 改变this指向 并 调用函数返回函数结果
// 具体一个应用 为伪数组借用数组的方法
var obj = {0:0;1:1}
// 但是没有插入的数组方法
Array.prototype.toString.call(obj, 2)
  1. bind 改变this指向 但 不调用函数 只返回函数体
// 原本定时器的this都是window 但是现在改为xxx
setInterval(function(){}.bind(xxx),1000)
  1. apply 改变this指向 并 调用函数返回函数结果 用于展开数组
// Math.max用于数字 但是 使用 apply改造给数组
arr = [1 ,2 ,3]
Math.max.apply(null,arr);
// null是this这里不改写null

9.函数4个属性

  1. arguments 或者 函数.arguments 表示 函数实参个数
  2. caller 全局为 null 调用者
  3. length 函数形参个数
  4. name 函数名
    都可使用console.dir(函数名)查看

高级函数用法

就是 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

你可能感兴趣的:(#,web,js,prototype,javascript,bind)