js基础知识梳理

从问题入手

学习知识基础是关键。在此记录关键问题,不断丰富。仅供本身学习。前端

问题

  • js内存分几类?分别用来存放什么?
  • 全局做用域和私有做用域
  • 内存释放
  • 什么叫预解释?
  • 全局变量和私有变量
  • 函数执行基本顺序
  • 代码执行变量获取顺序
  • 解释闭包
  • this的指向
  • 前端常接触的设计模式
  • var n1 = new Number和var n2 = 1有什么不一样?var a1 = new Array和var a2 = []有什么不一样?
  • 解释一下js的原型链

  • js内存分几类?分别用来存放什么?

answer:js分为栈内存和堆内存设计模式

堆内存用来存放引用数据类型的具体内容,object类型存储key value;function类型用来存放函数内容的字符串数组

栈内存用来提供一个js代码执行的环境。全局做用域和私有做用域都属于栈内存。浏览器

  • 全局做用域和私有做用域?

answer:bash

全局做用域:浏览器一打开就建立,浏览器关闭时才销毁。 私有做用域:函数执行才产生私有做用域。闭包

  • 内存释放?

answer:app

堆内存释放:引用数据类型定义的时候开辟一个新的堆内存,该内存有个引用地址。若是存在变量引用该地址,则内存被占用不可销毁。若想释放,则把他的内存指向null,当前堆内存没有被占用,则浏览器会在空闲时销毁。dom

栈内存释放:全局做用域浏览器一打开即建立,关闭才销毁。私有做用域,函数执行时产生,私有做用域的代码执行完了,则当前做用域被销毁。函数

可是,当前私有做用域的部份内容被当前做用域以外的内容占用了,当前做用域不能销毁学习

  1. 函数执行返回一个引用数据类型的值,而且在函数外被接收了。这种状况行程的私有做用域不会被销毁,好比返回一个函数、对象、数组、则该堆内存没法释放,与此同时,执行该堆内存的执行栈内存也没法释放。可是返回数字,字符串,布尔值,则直接返回值,函数执行产生的私有做用域执行一次销毁一次。
  2. 私有做用域中进行dom事件绑定,由于dom事件绑定,则该私有做用域也不能释放(dom绑定至关于返回一个函数,和状况1本质相同)。
  3. 函数执行返回的函数并无被其他变量接收,可是会紧接着执行一次,则该内存不会当即销毁,在执行完毕后再销毁。
function fn(){
    var num = 100;
    return function(){
        
    }
}
fn()()
复制代码
  • 什么叫预解释?

answer:也叫变量提高。在当前做用域中,js代码执行以前,浏览器首先会把带var 和 function 的进行提早声明或定义。(var 声明 function 声明+定义)

预解释只发生在当前做用域下,开始只对window下(全局做用域)下预解释,函数执行时对(私有做用域)下进行预解释。全局和私有做用域都存在预解释。

  • 全局变量和私有变量?

answer:

全局变量:全局做用域下定义的变量(全局下预解释)

私有变量:私有做用域中声明的变量 和 函数的形参。

  • 函数执行基本顺序?

answer:

  1. 生成一个新的私有做用域
  2. 若是有形参,先形参赋值
  3. 在私有做用域中进行预解释
  4. 在私有做用域中从上到下执行代码
  • 函数执行变量获取顺序?

answer:

  1. 先肯定私有变量中是否存在(形参+声明的私有变量),若是有优先使用私有变量。
  2. 若是没有则向上级做用域查找,直到window为止。
  3. 上级做用域只和函数定义有关,和在哪执行无关。在哪一个做用域下定义的,上级做用域就是谁。
  • 解释闭包?

answer:闭包是一种机制,函数执行时产生的私有做用域内的变量保护起来,不受外界干扰。

  • this的指向?

answer:仅表明当前行为的执行主体

和的当前执行的环境(区域)上下文无关; 和函数在哪定义,在哪执行无关;

  1. 函数执行,函数名前面有.则.前面为this;没有.window为this;
  2. 自执行函数中,this永远指向window;
  3. 给dom元素绑定事件,当前事件触发执行绑定方法,方法中的this执行当前dom元素。
  4. 构造函数模式中,函数体中(类中)的this中,指向当前类的一个实例。
  • 前端常接触的设计模式 answer:
  1. 单例模式:分组编写各自的功能模块。
  2. 工厂模式:相同功能代码,抽取到一个函数处理。
  3. 构造函数模式:建立类,并利用类的实例。
function Fn(){
    this.x = 100;
}
Fn.prototype.getX = function(){};
var f1 = new Fn
复制代码
构造函数模式注意点:
1. 不须要传参时,()能够省略。
2. 构造函数中的this指向某个实例,可是属性值内包含this,须要看.前面的内容。
复制代码
function Fn(){
    this.x = 100;
    this.getX = function(){
        console.log(this.x)
    }
}
var f1 = new Fn
复制代码
3. 构造函数里的var只是私有变量而已,和类、实例无关。
4. 构造函数模式中,**浏览器默认把实例返回**,返回一个**对象数据类型**的值。若是本身在构造函数中写return。return 基本数据类型的值,则当前实例不变。若return 引用数据类型,则当前实例为该引用数据类型。
复制代码
function Fn(){
    this.x = 100;
    return [1,2,3]
}
var f1 = new Fn;
console.log(f1); // [1, 2, 3]
复制代码
  1. 原型链模式:在构造函数基础上,解决属性共有问题。
  • var n1 = new Number和var n2 = 1有什么不一样?var a1 = new Array和var a2 = []有什么不一样?

answer:

new的形式是实例建立方式,n=1是对象字面量方式。前者是标准建立实例的方式。第二种是js弱类型语言独有的建立实例的方式。

针对引用数据类型:对象字面量,和类实例方式建立没有不一样。 针对基本数据类型:二者不一样。

var n1 = new Number(1);
var n2 = 1;
typeof(n1) // object
typeof(n2) //number
n1 instanceOf Number //true
n2 instanceOf number // false
复制代码
  • 解释一下js的原型链

答:

* 全部函数数据类型,都自带一个prototype属性,存储值为对象数据类型,浏览器默认开辟一个堆内存
* prototype在浏览器环境下,拥有一个constructor属性,指向当前类自己
* 每一个对象数据类型(普通对象,数组,正则,实例,prototype,函数),也天生自带一个属性__proto__。指向`当前实例所属类的原型(prototype)`
复制代码
  • 类的私有属性(方法)和公有属性(或方法)分别在哪定义?

答:

私有写到函数体中,this.的形式定义 公有写到prototye原型链中

  • 详细列出div元素;a元素;document;window的原型链?

答: 为何div元素有getElementsByClassName;可是却没有getElementById

  • 一个函数的多面性

答: 全部函数数据类型都是Function类的实例 全部类都是函数 每一个函数都是Object类的实例

一、普通函数 执行的时候造成私有做用域(闭包) 形参赋值 预解释 代码执行,执行完成后栈内存销毁or被占用而不能销毁 二、类 他有本身的实例,也有一个prototype属性指向原型 三、普通对象: 能够有本身私有属性(name,length,等等),也有__proto__指向Funtion的prototype 三者没有必然联系,每种角色,不混用!!!

特殊记忆: Function.prototype是函数数据类型的,可是相关操做和对象如出一辙。-->anonymous(匿名函数)

  • call的做用

call是存在于Function.prototype上的属性方法

call的做用在于:改变this关系

call执行:1)让fn中this变为obj ;2)再把fn中的内容执行完成。

概念化call原理以下:

// Function.prototype.call = mycall function (context) {
    // 一、让fn中this 关键字变成context的值
    // eval(this.toString().replace('this', 'context'));
    // 二、让fn执行
    // this();
// }
   // call 方法执行
   obj = {};
   fn.call(obj)
复制代码

call的测试题,以下四个输出结果

function fn1() {
    console.log(1);
}

function fn2() {
    console.log(2);
}
fn1.call(fn2); 
fn1.call.call(fn2); 
Function.prototype.call(fn1);
Function.prototype.call.call(fn1);
复制代码

结果:

1;2;undefined;1;

Function.prototype.call(fn1);// Function.prototype为空函数,this指向fn1,空函数执行,获得undefined

  • 严格模式和非严格模式下call执行的不一样点
"use strict"
function fn(num1, num2) {
    console.log(num1 + num2);
    console.log(this);
}
var obj = {
    'key': 'value'
};
fn(100, 200);
fn.call(100, 200);
fn.call(obj, 100, 200);
fn.call(); // this->window  严格模式下 undefined
fn.call(null); // this->window 严格模式下 null
fn.call(undefined); // this->window 严格模式下 undefined
复制代码
  • call apply bind 三者之间关系

call,apply做用相同,包含改变this指向+执行。不一样的是,call接收参数,apply接收数组做为参数。

bind,预先改变this执行,但不执行。预处理的性质。ie6-8不兼容

相关文章
相关标签/搜索