JS高级部分知识点

原型

显示原型和隐式原型

每个函数function都有一个protopyte,即显式原型(属性)
每个实例对象都有一个_proto_,可称为隐式原型(属性)
对象的隐式原型的值为其构造函数的显示原型的值

总结

函数的prototype属性:在定义函数时自动添加的,默认值是一个空object对象(但是object也是一个函数,且不满足默认值要求)
对象的_proto_属性:创建对象时自动添加的,默认值为构造函数的prototype属性值
在ES6之前,能直接操作显示原型,但不能直接操作隐式原型

function Fn(){   //内部语句:this.prototype = {}
    
}
console.log(Fn.prototype)
var fn = new Fn()   //this._proto_ = Fn.prototype
console.log(fn._proto_)
console.log(fn._proto_=== Fn.prototype)//true
//给原型添加方法
Fn.prototype.test=function(){
    console.log('test')
}
fn.test()

原型链

访问同一个属性时,先在自身属性中查找,找到返回;如果没有,再沿着_proto_这条链向上查找,找到返回;如果最终没找到,返回undefined
别名:隐式原型链
作用:查找对象的属性或者方法
如图所示
在这里插入图片描述

构造函数/原型/实例对象的关系

o1和o2是两个实例对象
所有函数的_proto_属性都是一样的

function Fn( ){ }
var Fn=new Function()   //Function也是构造函数
Function=new Function()

注意

1.函数的显示原型指向的对象默认值是空Object实例对象(但Object不满足)
在以上代码的基础上

console.log(Fn.prototype instanceof Object) //true
console.log(Object.prototype instanceof Object) //false
console.log(Function.prototype instanceof Object) //true

只有Object是例外
2. 所有函数都是Function的实例(包含Function)

console.log(Function._proto_===Function.prototype)//true

3.Object的原型对象是原型链尽头

console.log(Object.prototype._proto_) //null

原型链属性问题

1.读取对象的属性值时,会自动到原型链中查找
2.设置对象的属性值时,不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
3.方法一般定义在原型中,属性一般通过构造函数定义在对象本身上。

instanceof

作用:判断左边的对象是不是右边的实例
表达式:A instanceof B
如果B函数的显示原型对象在A对象的原型链上,返回true,否则返回false
Function是通过new自己产生的实例

执行上下文

1.代码分类:(根据位置)全局代码,函数(局部)代码
2.全局执行上下文
在执行全局代码前将window确定为全局执行上下文
对全局数据进行预处理(1.var定义的全局变量==>undefind,添加为window属性;2.function声明的全局函数==>赋值(fun),添加为window的方法;3.this==>赋值为全局方法)
开始执行全局代码
3.函数执行上下文
在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象(虚拟的,存在于栈中)
对局部数据进行预处理
(1.形参变量==>赋值(实参)>添加为执行上下文的属性;
2.arguments
>赋值(实参列表),添加为执行上下文的属性)

执行上下文栈

在这里插入图片描述

作用域与作用域链

作用域

就是一个“地盘”,一个代码所在的区域。它是静态的(相对于上下文对象),在编写代码时就确定了。

分类

全局作用域
函数作用域
没块作用域(ES6有了)

作用

隔离变量:不同作用域下同名变量不会有冲突

作用域与执行上下文的区别

在这里插入图片描述
在这里插入图片描述

作用域链

在这里插入图片描述
在这里插入图片描述

闭包

在这里插入图片描述

常见的闭包

1.将函数作为另外一个函数的返回值

function fn1{
    var a=1;
    function fn2{
        a++;
        console,log(a);
    }
    return fn2
}
var f=fn1()
f()//2
f()//3

2.将函数作为实参传递给另一个函数调用

function shoeDelay(msg,time){
    seTimeout(function(){
        alert(msg)
    },time)
}
showDelay('atguigu',2000)

闭包的作用

1.使用函数内部的变量在函数执行完以后,仍然存活在内存中(延长了局部变量的生命周期)
2.让函数外部可以操作(读写)到函数内部的数据(变量/函数)

注意

在函数外不能直接访问函数内部的局部变量
函数执行完之后,函数内部声明的局部变量一般不存在,存在于闭包中的变量才可能存在

闭包的生命周期

产生:在嵌套内部函数定义执行完时就产生了(不是在调用)
死亡:在嵌套的内部函数成为垃圾对象时

闭包的应用

定义JS模块
在这里插入图片描述
在这里插入图片描述

如果要暴露多个函数,将要暴露的对象封装起来

return {
    字符串1:方法1,
    字符串2:方法2
}

闭包的缺点和解决

缺点

函数执行完后,函数内的局部变量没有释放,占用内存时间会变长;
容易造成内存泄露

解决

能不用闭包就不用
及时释放

function fn1(){
    var arr=new Arry[10000]
    function fn2(){
        console.log(arr.length)
    }
    return fn2
}
var f=fn1()
f()

f=null//让函数内部成为垃圾对象--->回收闭包

内存溢出与内存泄漏

内存溢出

一种程序运行出现的错误
当程序运行需要的内存超过了剩余的内存时,就会抛出内容溢出的错误

内存泄漏

占用的内存没有及时释放
内存泄漏积累多了就容易导致内存溢出

常见的内存泄漏:

1.意外的全局变量
2.没有及时清理的计时器或回调函数
3.闭包

对象创建模式

Object构造函数模式

先创建空Object对象,再动态添加属性和方法
适用场景:起始时不确定对象内部数据
问题:语句太多

对象字面量模式

使用{}创建对象,同时指定属性/方法
适用场景:起始时对象内部数据是确定的
问题:如果创建多个对象,有重复代码

工厂模式

通过工厂函数动态创建对象并返回
适用场景:需要创建多个对象
问题:对象没有一个具体的类型,都是Object类型
工厂函数:返回一个对象的函数都是工厂函数

function createPerson(name,age){
    var obj={
        name:name,
        age:age,
        setName:function(name){
            this.name=name;
        }
    }
    return obj
}

自定义构造函数模式

自定义构造函数,通过new创建对象
适用场景:需要创建多个类型确定的对象
问题:每个对象都有相同的数据,浪费内存

构造函数+原型的组合模式

自定义构造函数,属性在函数中初始化,方法添加到原型上
适用场景:需要创建多个类型确定的对象

  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值