JS原型原型链作用域闭包等

JS高级

这里是对JS高级的一些总结~

显式原型和隐式原型

  1. 每个函数的function都有一个prototype,即显式原型属性,默认指向一个空的object对象

  2. 每个实例对象都有一个__proto__,可称为隐式原型

  3. 对象的隐式原型的值为其对应构造函数的显式原型的值

// 定义构造函数
function Fn() { //内部语句:this.prototype={}

    }
    console.log(Fn.prototype);
    var fn = new Fn()   // 创建实例对象
    console.log(fn.__proto__);  
    //内部语句this.__proto__ = Fn.prototype
    console.log(Fn.prototype === fn.__proto__);//true
    // 给原型添加方法
    Fn.prototype.test = function () {
        console.log('test()');
    }
    fn.test();//在object里面

在这里插入图片描述

原型链

  1. 原型链

访问一个对象的属性时,现在自身属性中查找,找到返回。如果没有,再沿着__proto这条链上查找,找到返回,如果没找到,返回undefined

  • 别名:隐式原型链
  • 作用:查找对象的属性(方法)
    在这里插入图片描述
  1. 构造函数/原型/实体对象的关系

实例对象的隐式原型等于构造函数的显式原型

a. 函数的显式原型指向的对象:默认是空的object实例对象(当object不满足)

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

b. 所有函数都是Function 的实例(包括Function)

console.log(Function.__proto__===Function.prototype);

//Object的原型对象是原型链的尽头
console.log(Object.prototype.__proto__) //null

//原型对象中有一个属性constructor,它指向函数对象
//fun.prototype.contructor===fun

在这里插入图片描述

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

    }
    Fn.prototype.a = 'xxx';
    var fn1 = new Fn();
    console.log(fn1.a, fn);

    var fn2 = new Fn();
    fn2.a = 'yyy'   //直接添加
    console.log(fn1.a, fn2.a, fn2);
function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.setName = function (name) {
        this.name = name;
    }
    var p1 = new Person('tom', 12);
    p1.setName('bob');
    console.log(p1);

instanceof

  • 表达式:A instanceof B

  • 如果B函数的显式原型对象在A对象的原型链上,则返回true,否则返回false

  • Function是通过new自己产生的实例

function Foo() {

    }
    var f1 = new Foo();
    console.log(f1 instanceof Foo); //true
    console.log(f1 instanceof Object); //true

原型链继承

内存溢出和内存泄漏

内存溢出

  • 一种程序运行出现的错误
  • 程序运行需要的内存超过了剩余的内存
例:
var obj={}
for(var i=0;i<10000;i++){
    obj[i] = new Array(100000)
    console.log('-----');
}

内存泄漏

  • 占用的内存没有及时泄漏

  • 内存泄漏积累多了就容易导致内存溢出

  • 常见的内存泄漏:

    1. 意外的局部变量

    2. 没有及时清理的定时器或回调函数

    3. 闭包

function fn() {
    a = 3;   // 直接赋值相当于全局变量
    console.log(a);
}
fn();

作用域与作用域链

查找变量:从作用域的顶端依次向下查找

GO:全局上下文

AO:执行器上下文

function a(){
    function b(){
        var b = 234;
    }
    var a = 123;
    b();
    console.log(a);
}
var glob = 100;
a();

//a defined a.[[scope]] --> 0: GO{}
//a doing   a.[[scope]] --> 0: AO{}
//                          1: GO{}

在这里插入图片描述

闭包

当内部函数被保存到外部(非全局变量)时,将会生成闭包。闭包会导致原有的作用域链不释放,造成内存泄漏(占用内存)。

闭包的作用
  • 实现公有变量
  • 可以做缓存(存储结构
  • 可以实现封装,属性私有化
  • 模块化开发,防止污染全局变量

预编译

1. 全局预编译

a. 创建GO对象(Golbal Object,可以理解为window)

b. 找到变量声明,赋值为undefined

c. 找到函数声明(function(){}),函数名作为GO的属性名,函数体作为GO的属性值

2. 函数中的预编译

a. 创建AO对象(Active Object, 即执行期上下文)

b. 找形参和参数声明,将变量和幸参作为AO的属性名,赋值为undefined

c. 将实参和实参统一

d. 在函数中找函数声明

JS用在本地存储一些函数

**push() **可向数组的末尾添加一个或多个元素,并返回新的长度。

注意: 新元素将添加在数组的末尾。

注意: 此方法改变数组的长度。

提示: 在数组起始位置添加元素请使用 unshift() 方法。


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值