自检清单(javascript)

变量和类型

  1. Javascript规定了几种语言类型
    数据类型一般分为七种:Number String Boolean null undefined Object Symbol
    基本类型:Number String Boolean null undefined 
    引用类型:Object Date Array RegExp Function

    String:并非字符串,而是字符串的UTF16编码

    Number:
    //加法运算中有+0和-0,但是除法中要区分,区别+0和-0的方式为
    console.log(1/+0) //Infinity
    console.log(1/-0) //-Infinity
    
    console.log( 0.1 + 0.2 == 0.3);//false
    //首先声明这不是bug,原因在与十进制到二进制的转换导致的精度问题!
    //正确的比较方法
    console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);//true
    console.log( 0.1*10 + 0.2*10 == 0.3*10) //true
    
    Boolean:true、false

    Object:
    1.JavaScript对象的定义是“属性的集合”。属性分为数据属性和访问器属性,二者都是 key-value 结构,key可以是字符串或者Symbol类型。
    2.JavaScript的“类”仅仅是运行时对象的一个私有属性,而JavaScript中是无法自定义类型的。
    3.Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。
    4.Symbol 函数比较特殊,直接用 new 调用它会抛出错误,但它仍然是Symbol对象的构造器。
    我们在原型上添加方法,都可以应用于基本类型。
    
    问题:为什么给对象添加的方法能用在基本类型上?
    答案:运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得能够在基础类型上调用对应对象的方法。
    null:表示不存在的对象,是关键字

    undefined:是一个变量,而非关键字,表示有值但是未定义,任何变量赋值前都是undefined

    Symbol:表示独一无二的值,是非字符串的对象key的集合。Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种就是字符串,另一种就是新增的Symbol类型。饭是属性名属于Symbol类型,就是独一无二的,可以保证不会与其它属性名产生冲突
    console.log(Symbol() === Symbol()); // false
    console.log(Symbol("Alice") === Symbol("Alice")); // false
    
    //Symbol值不能与其他类型的值进行运算
    console.log(Symbol('Alice') + "Bruce"); // 报错
    
    //Symbol值可以显式转为字符串,也可以转为布尔值,但是不能转为数值
    var symbol = Symbol("Alice");
    console.log(symbol.toString()); // 输出:Symbol(Alice)
    console.log(Boolean(symbol)); // 输出:Symbol(Alice)
    if (symbol) {
        console.log("YES"); // 输出:Yes
    }	
    console.log(Number(symbol)); // 报错:TypeError
  2. 理解值类型和引用类型
    值类型:
    String Number Boolean null undifined
    引用类型:Array Date Object RegExp Function

    区别一:
    存储位置不一样:
    值类型的变量会保存在栈内存中,如果在一个函数中声明一个值类型的变量,那么这个变量当函数执行结束后会自动销毁;引用类型的变量名会保存在栈内存中,但是变量值会存储在堆内存中,引用类型的变量不会自动销毁,当没有引用变量引用他时,系统的垃圾回收机制会回收他。
    栈内存 堆内存
    a=10  
    arr [1,2,3]
    区别二:
    复制方式不一样:
    值类型的变量直接复制就是深复制,比如var a = 10; var b = a; b = 20; console.log(a) //10;引用类型的变量直接赋值实际上是传递引用,只是浅复制
     

    区别三:
    值类型无法添加属性和方法,引用类型可以添加属性和方法

    区别四:
    值类型的比较和引用类型的比较:
    值类型的比较是值的比较,只要值相等他们就相等;引用类型的比较是值和引用地址的比较,值和引用地址都相等才相等。(注意==和===,==在比较时做了类型转换,转换成相同类型之后比较值;而===是比较值和类型)

  3. javascript八大数据结构
    自检清单(javascript)_第1张图片

    详情连接:https://blog.csdn.net/yeyazhishang/article/details/82353846

  4. javascript中变量在内存中的储存方式
    变量:
    可分为整形、浮点型、字符型、指针型,其值在其作用域内可以改变的量叫做变量。变量在其使用前必须定义,每一个变量都有自己的地址。js提供了parseInt()和parseFloat()两个转换函数,前者把值转换为整数,后者把值转换为浮点数。
    ???

  5. 判断数据类型的方式

    ① typeof:可以对基本类型做出准确判断,但对于引用类型,用他就有点力不从心了

          typeof 返回一个表示数据类型的字符串,返回结果包括:number、boolean、string、object、undefined、function等6种数据类型。
          typeof 可以对JS基本数据类型做出准确的判断(除了null),而对于引用类型返回的基本上都是object, 其实返回object也没有错,因为所有对象的原型链最终都指向了Object,Object是所有对象的`祖宗`。 但当我们需要知道某个对象的具体类型时,typeof 就显得有些力不从心了。
    ② instanceof:判断对象和构造函数在原型链上是否有关系,如果有关系,返回真,否则返回假

    function Aaa(){}
    var a1 = new Aaa();
    alert( a1 instanceof Aaa);  //true判断a1和Aaa是否在同一个原型链上,是的话返回真,否则返回假
    var arr = [];
    alert( arr instanceof Aaa);//false
    var str = 'hello';
    alert(str instanceof String);//false
    
    var bool = true;
    alert(bool instanceof Boolean);//false
    
    var num = 123;
    alert(num instanceof Number);//false
    
    var nul = null;
    alert(nul instanceof Object);//false
    
    var und = undefined;
    alert(und instanceof Object);//false
    
    var oDate = new Date();
    alert(oDate instanceof Date);//true
    
    var json = {};
    alert(json instanceof Object);//true
    
    var arr = [];
    alert(arr instanceof Array);//true
    
    var reg = /a/;
    alert(reg instanceof RegExp);//true
    
    var fun = function(){};
    alert(fun instanceof Function);//true
    
    var error = new Error();
    alert(error instanceof Error);//true

    从上面的运行结果我们可以看到,基本数据类型是没有检测出他们的类型,但是我们使用下面的方式创建num、str、boolean,是可以检测出类型的:

    var num = new Number(123);
    var str = new String('abcdef');
    var boolean = new Boolean(true);

    ③ constructor:查看对象对应的构造函数

    var str = 'hello';
    alert(str.constructor == String);//true
    
    var bool = true;
    alert(bool.constructor == Boolean);//true
    
    var num = 123;
    alert(num.constructor ==Number);//true
    
    var nul = null;
    alert(nul.constructor == Object);//报错
    
    var und = undefined;
    alert(und.constructor == Object);//报错
    
    var oDate = new Date();
    alert(oDate.constructor == Date);//true
    
    var json = {};
    alert(json.constructor == Object);//true
    
    var arr = [];
    alert(arr.constructor == Array);//true
    
    var reg = /a/;
    alert(reg.constructor == RegExp);//true
    
    var fun = function(){};
    alert(fun.constructor ==Function);//true
    
    var error = new Error();
    alert(error.constructor == Error);//true

    从上面的测试中我们可以看到,undefined和null是不能够判断出类型的,并且会报错。因为null和undefined是无效的对象,因此是不会有constructor存在的。
    同时我们也需要注意到的是:使用constructor是不保险的,因为constructor属性是可以被修改的,会导致检测出的结果不正确:

    function Aaa(){}
    Aaa.prototype.constructor = Aaa;//程序可以自动添加,当我们写个构造函数的时候,程序会自动添加这句代码
    function BBB(){}
    Aaa.prototype.constructor = BBB;//此时我们就修改了Aaa构造函数的指向问题
    alert(Aaa.construtor==Aaa);//false

    ④ Object.prototype.toString
    toString是Object原型对象上的一个方法,该方法默认返回其调用者的具体类型,更严格的讲,是 toString运行时this指向的对象类型, 返回的类型。基本上所有对象的类型都可以通过这个方法获取到。 

    var str = 'hello';
    console.log(Object.prototype.toString.call(str));//[object String]
    
    var bool = true;
    console.log(Object.prototype.toString.call(bool))//[object Boolean]
    
    var num = 123;
    console.log(Object.prototype.toString.call(num));//[object Number]
    
    var nul = null;
    console.log(Object.prototype.toString.call(nul));//[object Null]
    
    var und = undefined;
    console.log(Object.prototype.toString.call(und));//[object Undefined]
    
    var oDate = new Date();
    console.log(Object.prototype.toString.call(oDate));//[object Date]
    
    var json = {};
    console.log(Object.prototype.toString.call(json));//[object Object]
    
    var arr = [];
    console.log(Object.prototype.toString.call(arr));//[object Array]
    
    var reg = /a/;
    console.log(Object.prototype.toString.call(reg));//[object RegExp]
    
    var fun = function(){};
    console.log(Object.prototype.toString.call(fun));//[object Function]
    
    var error = new Error();
    console.log(Object.prototype.toString.call(error));//[object Error]

    从这个结果也可以看出,不管是什么类型的,Object.prototype.toString.call();都可以判断出其具体的类型。

    ⑤ 下四种方法各自的优缺点

    不同类型的优缺点 typeof instanceof constructor Object.prototype.toString.call()
    优点 使用简单 能检测出引用类型 基本能检测所有的类型(除了null和undefined) 检测出所有的类型
    缺点 只能检测出基本类型(除null) 不能检测基本类型,且不能跨iframe constructor易被修改,也不能跨iframe IE6下,undefined和null均为Object

     

原型和原型链

  1. 几种继承方式及他们的优缺点
    https://blog.csdn.net/caijixin/article/details/78295676
     
  2. new一个对象的详细过程,手动实现一个new操作符
    function Person() {
        var this = {
            __proto__: Person.prototype
        }
        this.name = name
        this.age = age
        return this
    }
    var person = new Person()
    系统会在内部创建一个this对象,将__proto__转到构造函数的prototype上面,最后再隐式的把this对象return出来,所以person就是一个this对象。
     
  3. 理解词法作用域和动态作用域
    词法作用域:也就是静态作用域
    function foo(){
        console.log(a);//2
    }
    function bar(){
        var a=3;
        foo();
    }
    var a=2;
    bar();
    动态作用域:
    function foo(){
        console.log(a);//3(而不是2!)
    }
    function bar(){
        var a=3;
        foo();
    }
    var a=2;
    bar();
    主要区别: 
    词法作用域是在写代码或者说定义时确定的,而动态作用域是在运行时确定的。 
    词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用。
     

作用域和闭包

  1. javascript的作用域
    在ES5中,没有块级作用域,JS的作用域分为函数作用域全局作用域两种。
    在ES6中,新增了let和const,这两个类型的变量只存在于块级作用域中,并且不存在变量提升
  2. 闭包的作用
    ①可以读取自身函数外部的变量
    ②让这些外部变量始终保存在内存中
  3. this
    ①ES5,this是在函数调用时被绑定的,它指向哪里取决于在哪里被调用

执行机制

  1. 312312
  2.  

 

 

 

语法和API

 

你可能感兴趣的:(javascript)