5. 原型链
-
js的所有对象都是继承自对象,每个对象都有他的原型,原型链就是先查找此实例的属性和方法,如果没有则寻找他的原型,再没有再接着向上找原型
比如:Student继承自Person,Person的原型又是Object
class Person { constructor(name) { this.name = name } eat() { console.log(`姓名 ${name} eat something`) } } class Student extends Person{ constructor(name,age){ super(name) this.age = age } sayHi() { console.log(`姓名 ${this.name} 年龄 ${this.age}`) } } //创建实例 const xialuo = new Student('夏洛',18) console.log(xialuo); console.log(xialuo.name); xialuo.sayHi()
image.png -
实例的proto 与原型的prototype相等,每个Object的原型都是null
xialuo.__proto__ === Student.prototype Student.prototype.__proto__ === Person.prototype Person.prototype.__proto__ === Object.prototype Object.prototype.__proto__ == null
-
instanceof只能判断引用(合成)类型,
xialuo instanceof Student xialuo instanceof Person xialuo instanceof Object Student instanceof Object Person instanceof Object
-
hasOwnProperty,查找自身的属性方法
xialuo.hasOwnProperty('name')//true xialuo.hasOwnProperty('sayHi')//false
链式操作?链式操作是返回一个this,然后接着向下调用;链式操作有一个缺点,需要返回this,所以使用时得最后一个是返回值,或者没有返回值
例如:function Person(){};
var person = new Person();
//实现person.set(10).get()返回20
function Person() {
}
Person.prototype = {
set(value) {
this.value = value
return this
},
get() {
return this.value * 2
}
}
let person = new Person()
console.log(person.set(10).get());
6. 作用域和自由变量
作用域有全局作用域,函数作用域,块级作用域
-
自由变量,先在当前作用域查找,如果没有向上一层作用域查找,没有再向上,还是没有则返回xxx is not defined
let a = 10; function f1() { let b = 20; function f2() { let c = 30; let sum = a+b+c; console.log(sum) } f2() } f1()
7. 闭包
-
什么是闭包?
闭包就是将函数内部与外部连接,比如想用在数内定义的变量,就可以在函数内重新定义一个函数,将此变量返回
-
在闭包中的自由变量使用?
函数中的自由变量,无论什么时候都是函数定义时的作用域,一层一层向上查找,而不是使用时的作用域
a.函数作为返回值
function getName() { const name = 'zhangsan' return function () { console.log(name) } } let person = getName() const name = 'lisi' person()//zhangsan
b. 函数作为参数传递
function getAge(fn) { const age = 18 fn() } const age = 20 function nowAge() { console.log(age) } getAge(nowAge)//20
-
闭包的使用场景?
- 闭包隐藏数据,如何做一个简单的cache工具?
function createCache() { //需要隐藏的数据 const data = {} //返回的闭包 return { set(key,val) { data[key] = val }, get(key) { return data[key] } } } const c = createCache(0,100) c.set('a',100) console.log(c.get('a'))
影响:闭包中的变量会得不到释放,尽量少用
题,函数作为返回值:传参,调用问题
函数未声明时,如果没有特殊声明,第一次调用只返回第一层结果,第二次调用才会返回闭包,第三次及以后都是返回闭包
let scope = "global scope";
function checkScope() {
let scope = "local scope";
return function () {
console.log(scope);
}
}
var c1 = checkScope();//只调用checkScope,未调用闭包
c1();//调用闭包,local scope,闭包中的自由变量,永远指向定义时的作用域
c1();//再次调用闭包,local scope,闭包中的自由变量,永远指向定义时的作用域
alert调用的是toString
function f(x) {
let sum = 1;
let tmp = function (x) {
sum = sum + x;
return tmp;
}
tmp.toString = function () {
return sum;
}
return tmp;
}
alert(f(1))//1,第一次只调用到let sum = 1
alert(f(1)(2))//3,调用f,tmp函数,返回sum值
alert(f(1)(2)(3))//6,再次调用tmp函数
函数声明后,则相当于调用此函数
function f(obj1,obj2) {
console.log(obj1,obj2);//1 2
return obj1+obj2;
}
function f1(pro) {
console.log(pro);//'pro'
var obj1 = 1,obj2 = 2;
return f(obj1,obj2);//调用函数
}
let c1 = f1("pro");