js基础知识(二)

一、js原型和原型链

1、原型讲解:

普通的对象:是没有prototype属性的,只有隐藏属性__proto__,

原型对象:person.prototype还有constructor属性,属于普通对象

函数对象:所有的函数都拥有__proto__、prototype属性(指向原型对象)

其实原型对象就是构造函数的一个实例对象;

例如:

a和b,都得到了Dog对象的实例,这时a和b等于Dog的原型对象,a.name相当于获取的是原型对象上的name;b.name赋值的时候,相当于是在构造函数Dog里添加了新的name属性

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

实例的__proto__指向原型对象,原型对象的__proto__指向构造函数,如图:

关系图


2、原型链是实现继承的主要方法

原型链的基本思路:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针(constructor),而实例对象都包含一个指向原型对象的指针(__ptoto__),如果让原型对象等于另一个类型的实例,此时的原型对象将包含另一个指向原型的指针(__ptoto__),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型是实例...,这就构成了原型与实例的链条。


如图:


原型链

二、js作用域和闭包

1、执行上下文

变量提升:

一个标签为一个执行上下文,js在执行第一行代码的时候,会将所有定义的变量,声明的函数先提取出来,这个行为叫变量提升


变量提升在不同的方面,影响也不同:

变量声明:使用var,let,const关键字

函数声明:使用function(){}语法

类声明:使用class关键字

这些详细的区别:

使用var声明的变量会被提升到所在函数作用域的顶部。如果声明之前访问该变量。它的值会是undefined。

使用let,const声明的变量会被提升到所在块级作用域的顶部。如果声明之前访问该变量则会报错。

函数声明的提升允许在所属作用域内的任何地方使用该函数,不会抛出异常

类声明也会被提升到块级作用域的顶部,在声明之前使用类,会抛出异常

2、this

this在执行的时候才能确定,定义时无法确定

this在构造函数,对象,函数中使用的区别


构造函数中的this


对象中的this


函数中的this


call,apply,bind的区别

3、作用域,作用域链

js没有块级作用域,只有函数和全局作用域

js采用函数作用域

js中如果函数中嵌套函数就会出现作用域链

4、闭包

js闭包就是在另一个作用域中保存它从上级函数或作用域得到的变量,而这些变量是不会随上一级函数执行完成而销毁。

闭包就是在函数内部对外部作用域上变量的引用,使其常驻内存中,得不到释放。

例:


闭包创建

上面代码中,在函数体内定义另外的函数作为目标对象的方法函数,而这个对象的方法函数反过来引用外层函数体中的临时变量,当其中一个这样的内部函数在包含它们外部函数之外被调用时,就会形成闭包。


js的垃圾回收原理:

在js中如果一个对象不再被引用,那么这个对象会被GC回收,如果两个对象互相引用,而不再被第三者使用,那么这两个互相引用的对象也会被回收。在js中使用闭包,会给js的垃圾回收制造难题,尤其遇到对象间复杂的循环引用时,搞不好会造成内存泄漏。

你可能感兴趣的:(js基础知识(二))