Javascript高级笔记(一)

一、数据类型


    1、分类:

            1)基本(值)类型
                    String:任意字符串
                    Number:任意数值
                    boolean:true / false
                    undefined:undefined
                    null:null
            2)对象(引用)类型
                    Object:任意对象
                    Array:特别的对象(内部数据有序/ 数据下标)
                    Function:特别的对象(可以执行)

    2、判断:

            1)typeof:判断变量的类型
                    
                    * 可以判断 undefined / 数值 / 字符串 / 布尔值 / function
                    * 不可以判断 null 与 object 、 object 与 array
    var b1 = {
        b2: [1,'abc',console.log],
               b3:  function(){
                    console.log('b3');
                    return function(){
                        return 'xfzhang';
                    }
               }
    }

    console.log(typeof b1.b2) // 'object'
            2)instanceof:判断对象的具体类型(返回数据类型的字符串表达)true / false
   
console.log(b1 instanceof Object, b1 instanceof Array);
            3)=== (不可以是== 因为==会自动进行类型转换) true / false
                * undefined 、null

    3、相关问题:

            1) 实例:实例对象
                 类型:类型对象
    function Person(name,age){ // 构造函数 类型
        this.name = name;
        this.age = age;
    }

    var p = new Person();  // 根据类型创建的实例对象
            2)undefined 与 null 的区别?
                * undefined 代表定义了未赋值
                * null 定义并赋值了,只是值为null
  var a;
    console.log(a); // undefined
    a = null;
    cosnole.log(a); // null

            3)什么时候给变量赋值为null?

                * 初始赋值,表明将要赋值为对象
                
                * 结束前,让对象成为垃圾对象(被垃圾回收器回收)

    // 起始
    var b = null; // 初始赋值为null,表明将要赋值为对象
    // 确定对象就赋值
    b = ['abc', 12];
    // 最后
    b = null; // 将b指向的对象成为垃圾对象(被垃圾回收器回收)
            4)严格区别变量类型与数据类型?
                ① 数据的类型
                    * 基本类型
                    
                    * 对象类型
                ② 变量的类型(变量内存值的类型)
                    * 基本类型:保存的就是基本类型的数据
                
                    * 引用类型:保存的是地址值

二、数据、变量、内存


    1、什么是数据?

            ① 存储在内存中代表特定信息的东西(本质是二进制0101)
            ② 数据的特点:
        
                * 可传递

                * 可运算

    var a = 3;
    var b = a;

    var a = 3;
    var b = a + 2;
        ③ 一切皆数据    
        ④ 内存中所有操作的目标:数据
            * 算数运算
            * 逻辑运算
            * 赋值
            * 运算函数

    2、什么是内存?

            ① 内存条通电后产生的可存储数据的空间(临时的)
            ② 一块小内存的2个数据
                * 内部存储的数据
                * 地址值
    
            ③ 内存分类
             
                * 栈:全局变量、局部变量(空间较小)
                *堆:对象 (空间较大)

    3、什么是变量?

            * 可变化的量,由变量名和变量值组成
            * 每个变量都对应一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的数据

    4、内存、数据、变量三者之间的关系

            * 内存是用来存储数据的临时空间
            
            * 变量是内存的标识,我们通过变量找到对应的内存,进而操作(读 / 写)内存中的数据

    5、相关问题1

            ① var a = xxx, a 内存中到底保存的是什么?
                * xxx是基本数据,保存的就是这个数据
                * xxx是对象,保存的是对象的地址
                * xxx是一个变量,保存的是xxx的内存内容(可能是基本数据,也可能是地址值)
    var a = function(){ }
            ② 关于引用变量赋值问题
                * n个引用变量指向同一个对象,通过一个变量修改对象内部数据,其他所有变量看到的是修改之后的数据
 
   var obj1 = {name:'Tom'};
    var obj2 = obj1; // 将obj1内存的内容保存到obj2
    obj1.name = 'Jack';
    console.log(obj2.name); //'Jack
             * 2个引用变量指向同一个对象,让其中一个引用变量指向另一个对象,另一个引用变量仍然指向前一个对象
  var a = {age:12};
  var b = a;
  a = {name: 'BoB',age:13};
  b.age = 14;
  console.log(b.age,a.name,a.age); // 14 Bob 13
  function fn(obj){
        obj = {age:15}
  }
  fn(a);
  console.log(a.age); // 13

    6、相关问题2

            ① 在js调用函数时传递变量参数时,是值传递还引用传递?
                
                * 理解1:都是值(基本/ 地址值)传递
                * 理解2:可能是值传递,也可能是引用传递(地址值)
            ② JS引擎如何管理内存?
                Ⅰ 内存生命周期
    
                    * 分配小内存空间,得到它的使用权
                    * 存储数据,可以反复进行操作
                    * 释放小内存空间
                Ⅱ 释放内存
                    * 局部变量:函数执行完自动释放
                    * 全局变量:成为垃圾对象 ---> 垃圾回收器回收
    function fn(){
        var b = {}
    }
    fun(); // b是自动释放,b所指向的对象是在后面的某个时刻由垃圾回收器回收

三、对象


    1、什么是对象?

            * 多个数据的封装体
    
            * 用来保存多个数据的容器
            * 一个对象代表现实中的一个事物

    2、为什么要用对象?

            * 统一管理多个数据

    3、对象的组成

            ① 属性:属性名(字符串)和属性值(任意)组成
                * 代表现实事物的状态数据
        
            ② 方法:一种特别的属性(属性值是函数)
                * 代表现实事物的行为数据

    4、如何访问对象内部数据?

            ① * . 属性名:编码简单,有时不能用
                * [ ' 属性名 ' ]:编码麻烦,能通用
    var p = {
        name: ' Tom ',
        age: 12,
        setName: function(name){
            this.name = name;
        },
        setAge:function(age){
            this.age = age;
        }
    }

    p.setName('Bob');
    p['setAge'](23);
    console.log(p.name,p['age'])
            ② 什么时候必须使用[ ' 属性名 ' ]的方式?
    
                * 属性名包含特殊字符: -  空格
                * 属性名不确定
    var p = {}
    1. 给p对象添加一个属性:content-type:text/json
    p.content-type = 'text/json' //不能用
    p['content-type'] = 'text/json'

    2.属性名不确定
    var propNmame = 'myAge';
    var value = 18;
    p.proName = value; //不能用
    p[proName] = value

四、函数


    1、什么是函数?

            * 实现特定功能的n条语句的封装体
            * 只有函数是可以执行的,其他类型的数据不能执行

    2、为什么要用函数?

            * 提高代码复用
            * 便于阅读交流

    3、如何定义函数?

 
            * 函数声明

    function fn1(){
        console.log('fn1()')
    }

            * 表达式

  var fn2 = function(){
        console.log('fn2()')
    }    

    4、如何调用(执行)函数?

            * test():直接调用
            * obj.test():通过对象调用
            * new test():new调用
            * test.call / apply(obj):临时让test成为obj的方法进行调用
    var obj = {}
    function test2(){
        this.xxx = 'guigu'
    }
    obj.test2(); // 错误
    test2.call(obj); //js可以让一个函数成为指定任意对象的方法进行调用
    console.log(obj.xxx);

五、回调函数


    1、什么函数才是回调函数?

            * 你定义的
            * 你没有调
            * 但最终它执行了(在某个时刻或某个条件下)

    2、常见的回调函数?

            * dom事件回调函数 ---> this是发生事件的dom元素(例如:button)
            * 定时器回调函数 ---> this是window
            * ajax请求回调函数
            * 声明周期回调函数

六、IIFE


    1、理解

            * 全称:Immediately-Invoked Function Expression 立即调用函数表达式
            * 别名:匿名函数自调用
   (function(){  // 匿名函数自调用
        var a = 3;
        console.log(a+3);
    })()
    

    2、作用

        
            * 隐藏实现
            * 不会污染外部(全局)命名空间
            * 用它来编写js模块
   (function(){
        var a = 1;
        function test(){
            console.log(++a);
        }
        window.$ = function(){ // 向外暴露一个全局函数
            return {
                test:test;
            }
        }
    })();

    $().test();    // 1.$是一个函数 2.$执行后返回的是一个对象

七、函数中的this


    1、this是什么?

            * 任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window        
    
            * 所有函数内部都有一个变量this
            * 它的值是调用函数的当前对象

    2、如何确定this的值? 

 
            * test( ):window

            * p.test( ): p
    
            * new test( ):新创建的对象

            * p.call(obj):obj
            
function Person(color) {
    console.log(this)
    this.color = color;
    this.getColor = function () {
      console.log(this)
      return this.color;
    };
    this.setColor = function (color) {
      console.log(this)
      this.color = color;
    };
  }

  Person("red"); //this是谁? window

  var p = new Person("yello"); //this是谁? p

  p.getColor(); //this是谁? p

  var obj = {};
  p.setColor.call(obj, "black"); //this是谁? obj

  var test = p.setColor;
  test(); //this是谁? window

  function fun1() {
    function fun2() {
      console.log(this);
    }

    fun2(); //this是谁? window
  }
  fun1();

八、关于语句分号问题


    1、在下面两种情况下不加分号会有问题

            * 小括号开头的前一条语句
            * 中括号开头前一条语句 

    2、解决方法:在行首加分号

    var a = 3
    ;(function(){})()

九、复习


    
        1、形参的本质是变量、实参的本质是数据
        2、什么时候是垃圾对象?没有一个引用指向的时候

十、函数的prototype


    1、函数的prototype属性

            * 每个函数都有一个prototype属性,它默认指向一个Objec t空对象(即称为:原型对象)
            * 原型对象中有一个属性constructor,它指向函数对象
    

    2、给原型对象添加属性(一般都是方法)

            * 作用:函数的所有实例对象自动拥有原型中的属性(方法)
    

十一、显式原型与隐式原型


    1、每个函数function都有一个prototype,即显式原型

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

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

    4、内存结构

            * 函数对象是在定义的时候就创建了

    5、总结:

        * 函数的prototype属性:在定义函数时自动添加的,默认值是一个空Object对象
        * 对象的__proto__属性:创建对象时自动添加的,默认值为构造函数的prototype属性值
        * 程序员能直接操作显式原型,但不能直接操作隐式原型(ES6之前)

十二、原型链


    1、原型链

            * 访问一个对象属性时
    
                * 先在自身属性中查找,找到返回
                * 如果没有,再沿着__proto__这条链向上查找,找到返回
                * 如果最终没有找到,返回undefined
        
            * 别名:隐式原型链
            * 作用:查找对象的属性(方法)

    2、构造函数 / 原型 / 实体对象的关系

            *函数对象是Function的实例
 function Foo(){ }  <---->  var Foo = new Function()
    3、构造函数 / 原型 / 实体对象的关系2
            * 函数的显式原型指向的对象默认是空Object实例对象(但Object不满足)
  console.log(Fn.prototype instanceof Object)  // true
  console.log(Object instanceof Object)      // false
  console.log(Function.prototype instanceof Object)    // true
            * 所有函数都是Function的实例(包含Function)
    console.log(Function.prototype === Function.__proto)  // true
            * Object的原型对象是原型链的尽头
    console.log(Object.prototype.__proto)  // null

十二、原型链_属性问题


    1、读取对象的属性值时:会自动到原型链中查找

    2、设置对象的属性值时:不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值

    3、方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

十三、探索 instanceof

(判断左边的对象是否为右边类型的实例)


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

    2、instanceof是如何判断的?

            * 表达式:A instanceof B
            * 如果B函数的显式原型对象在A对象的原型链上,返回true,否则返回false
  //案例1
  function Foo() {  }
  var f1 = new Foo();
  console.log(f1 instanceof Foo);    // true
  console.log(f1 instanceof Object);    // true
  //案例2
  console.log(Object instanceof Function)    // true
  console.log(Object instanceof Object)    // true
  console.log(Function instanceof Object)    // true
  console.log(Function instanceof Function)    // true
  function Foo() {}
  console.log(Object instanceof  Foo);    // false

十四、面试题


  /*
  测试题1
   */
  var A = function() { }
  A.prototype.n = 1

  var b = new A()

  A.prototype = {
    n: 2,
    m: 3
  }

  var c = new A()
  console.log(b.n, b.m, c.n, c.m) // 1 undefined 2 3

  /*
   测试题2
   */
  var F = function(){};
  Object.prototype.a = function(){
    console.log('a()')
  };
  Function.prototype.b = function(){
    console.log('b()')
  };
  var f = new F();
  f.a() // true
  f.b() // false
  F.a() // true
  F.b() // true

十五、变量提升与函数提升


  1、变量声明提升

            * 通过var定义(声明)的变量,在定义语句之前就可以访问到
            * 值:undefined

    2、函数声明提升

        
            * 通过function声明的函数,在之前就可以直接调用
            * 值:函数定义(对象)

    3、问题:变量提升和函数提升是如何产生的?

十六、执行上下文


    1、代码分类(位置)

            * 全局代码
            * 函数(局部)代码

    2、全局执行上下文

            * 在执行全局代码前将window确定为全局执行上下文
            * 对全局数据进行预处理
                * var定义的全局变量 ==>undefined,添加为window的属性
                * function声明的全局函数 ==> 赋值(fun),添加为window的方法
                * this ==> 赋值(window)

    3、函数执行上下文

            * 在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象
            * 对局部数据进行预处理
                * 形参变量 ==> 赋值(实参)==> 添加为执行上下文的属性
                * arguments ==> 赋值(实参列表),添加为执行上下文的属性
                * var 定义的局部变量 ==> undefined,添加为执行上下文的属性
                * function 声明的函数 ==> 赋值(fun),添加为执行上下文的方法
                * this ==> 赋值(调用函数的对象)
            * 开始执行函数体代码

十七、执行上下文栈


    1、在全局代码执行前,JS引擎就会创建一个栈来存储管理所有的执行上下文对象
    2、在全局执行上下文(window)确定后,将其添加到栈中(压栈)
    3、在函数执行上下文创建后,将其添加到栈中(压栈)
    4、在当前函数执行完后,栈中只剩下window

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值