知识点
- 原型链
- this的指向
- 作用域和预解析
- new 关键字
- 闭包
- 继承
原型链
什么是原型链
1.1 由于proto是任何对象都有的属性,而js里万物皆对象,所以会形成以proto链接起来的链条,递归访问proto必须最终到头,并且值为null
当js 引擎查找对象的属性时,先查找对象本身是否存在该属性,如果不存在,会在原型链上查找,但不会查找自身的prototype
1.2 只有函数有prototype,对象是没有的。但是函数也是有proto的,因为函数也是对象。函数的proto指向的是Function.prototype。
instanceof 的原理
126.pnginstanceof是判断实例对象的proto和生成该实例的构造函数的prototype是不是引用的同一个地址。是返回true,否返回false。
例子
var F = function() {};
Object.prototype.a = function() {
console.log("aa");
};
Function.prototype.b = function() {
console.log("bb");
};
var f = new F();
F.a(); //aa
F.b(); //bb
f.a(); //aa
f.b(); // 抱错,f.b is not a function
this 的指向(有四种)
第一种 :方法调用 this 指向调用它的对象
var age = 38;
var obj = {
age: 18,
getAge: function() {
console.log(this.age); // age=18
}
};
obj.getAge();
--------------------------------------------------
// 变式:
var fn = obj.getAge;
fn();
第二种:函数调用 里面的this指向window
var age = 38;
var obj = {
age: 18,
getAge: function() {
var fn = function() {
console.log(this.age);// age=38
};
fn();
}
};
obj.getAge();
第三种:构造函数调用 this绑定到当前创建的对象实例。
var age = 38;
var obj = {
age: 18
};
var getAge = function() {
console.log(this.age); //age =18
};
obj.get = getAge;
obj.get();
第四种 上下文模式 this 指向谁? this指向的是传入的对象
call 和apply
var arr = [1,3,4,6,7,555,333,13]
console.log(Math.max(1,2,3,4,5))
console.log(Math.max.apply(arr,arr)) //this指向arr
console.log(Math.max.call(arr,1,3,4,6,7,555,333,13))
//伪数组 是一个对象: 访问方式:和数组一样,不能使用数组的方法
function sum(){
console.log(arguments[2]);
console.log(Array.prototype.join.call(arguments,"-"))
arguments.join("-")
}
sum("aa","bb","cc")
作用域和预解析
let const 函数作用域 ,{}
预解析(将声明的变量提前,声明的函数提前))只支持es5 ,不支持es6 。
new 关键字的作用
- 在函数里面创建一个对象obj
- 将函数里面的this指向创建的那个对象obj
- 返回这个obj对象
闭包
- 什么是闭包
闭包就是能够读取其他函数内部变量的函数,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 - 有什么用
1、可以读取函数内部的变量。
2、让这些变量的值始终保持在内存中,不会自动清除。 - 使用闭包的注意点
1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
例子
var counter = (function() {
//命名空间
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
})();
继承
es5继承(有三种)
第一种 构造函数继承( 缺点是:原型上的方法或者属性,无法继承)
function Fn(){
this.name = "zhangsan",
this.age = 12
this.eat = function(){
console.log("eat")
}
}
Fn.prototype.sleep = function(){
console.log("sleep")
} // 无法继承
function F(){
console.log(this)
Array.prototype.join.call(obj,'-') // 上下文模式 call 和 apply
Array.prototype.join.apply(obj,['-'])
Fn.call(this)
}
var fn = new Fn()
console.log(fn)
var f = new F()
console.log(f.sleep())
第二种 原型继承
缺点是: 共用一个原型对象,导致谁修改原型对象的值,其余对象都会被更改
function Fn(){
this.name = "zhangsan"
this.age = 12
this.color = ["yellow", "pink"]
this.eat = function(){
console.log("eat")
}
}
Fn.prototype.sleep=function(){
console.log("sleep")
}
function F(){}
F.prototype = new Fn()
var f = new F()
var f1 = new F()
f.color.push("black")
console.log(f1.color)// color=['yellow','pink','black']
第三种 组合方式
function Fn(){
this.name = "zhangsan"
this.age = 12
this.color = ["yellow", "pink"]
this.eat = function(){
console.log("eat")
}
}
function F(){
Fn.call(this) // this指向 Fn()
}
F.prototype = Object.create(Fn.prototype)
// F.prototype = Fn.prototype.constructor === Fn
F.prototype.constructor = F
var f = new F()
var f1 = new F()
f.color.push("black")
console.log(f1.color) //color =["yellow", "pink"]
function FCC(){}
console.log(f instanceof FCC)
console.log(f instanceof Fn)
es6 继承
- 通过extends 关键字来继承
- 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工,如果不调用super方法,子类就得不到this对象。因此,只有调用super之后,才可以使用this关键字。
class People{
constructor(name,age,skin){
this.name = name,
this.age = age
this.skin = skin
}
eat(){
console.log("eat")
}
sleep(){
console.log("sleep")
}
speak(){
console.log("speak")
}
}
class Student extends People{
constructor(name,age,skin,id,classs){
super(name,age,skin)
this.id = id
this.classs = classs
}
study(){
console.log("study")
}
}
var stu = new Student("zhangsan",12,"yellow",110,'一年级01班')
网友评论