zoukankan      html  css  js  c++  java
  • 全栈工程师知识点汇总——javascript(上)

    # JS高级第一天
    ## JS基本介绍
    + JS的用途:Javascript可以实现浏览器端、服务器端(nodejs)。。。
    + 浏览器端JS由以下三个部分组成:
    - ECMAScript:基础语法(数据类型、运算符、函数。。。)
    - BOM(浏览器对象模型):window、location、history、navigator。。。
    - DOM(文档对象模型):div、p、span。。。
    + ECMAScript又名es,有以下重大版本:
    - 旧时代:
    - es1.0。。。es3.1
    - 新时代:
    - es5
    - es6(es2015)
    - es7(es2016)、es8(es2017)

    ## 数据类型
    + 基本数据类型——值类型:(数字、字符串、布尔值、null、undefined)
    - undefined类型?
    1、一个变量声明了,但是没有赋值,值默认为undefined
    2、一个变量声明了,并且赋值了一个undefined的值
    3、一个对象中,获取某个不存在的属性,值也是undefined

    + 复杂数据类型——引用类型:(对象)
    - 数组
    - 函数
    - 正则表达式
    - Date

    ## 对象的基本使用
    ### 创建一个对象
    ```js
    var student={
    name:"李白" , //student有一个name属性,值为"李白"
    grade:"初一" ,
    //a、student有一个say属性,值为一个函数
    //b、student有一个say方法
    say:function(){
    console.log("你好");
    },
    run:function(speed){
    console.log("正在以"+speed+"米/秒的速度奔跑");
    }
    }
    ```

    ### 对象是键值对的集合:对象是由属性和方法构成的
    (也有说法为:对象里面皆属性,认为方法也是一个属性)

    + name是属性 grade是属性
    + say是方法 run是方法

    ### 对象属性操作

    #### 获取属性:

    #### 第一种方式:.语法
    + student.name 获取到name属性的值,为:"李白"
    + student.say 获取到一个函数

    #### 第二种方式:[]语法
    + student["name"] 等价于student.name
    + student["say"] 等价于student.say

    #### 号外:2种方式的差异:

    + .语法更方便,但是坑比较多(有局限性),比如:
    - .后面不能使用js中的关键字、保留字(class、this、function。。。)
    - .后面不能使用数字
    ```js
    var obj={};
    obj.this=5; //语法错误
    obj.0=10; //语法错误
    ```

    + []使用更广泛

    - o1[变量name]

    - ["class"]、["this"]都可以随意使用 `obj["this"]=10`

    - [0]、[1]、[2]也可以使用
    - `obj[3]=50 = obj["3"]=50`
    - 思考:为什么obj[3]=obj["3"]

    - 甚至还可以这样用:["[object Array]"]
    - jquery里面就有这样的实现

    - 也可以这样用:["{abc}"]
    - 给对象添加了{abc}属性

    #### 设置属性

    + `student["gender"]="男"`
    等价于: `student.gender="男"`
    - 含义:如果student对象中没有gender属性,就添加一个gender属性,值为"男"
    - 如果student对象中有gender属性,就修改gender属性的值为"男"

    + 案例1:`student.isFemale=true`

    + 案例2:`student["children"]=[1,2,5]`

    + 案例3:

    student.toShanghai=function(){
    console.log("正在去往上海的路上")
    }


    #### 删除属性

    + delete student["gender"]
    + delete student.gender
    (delete只能删除对象中的属性,不能删除变量)


    ##通过字面量方式创建对象的缺点:
    1、存在很多冗余代码。
    2、所有实例对象具有相同的属性和方法,会导致内存浪费(内存泄漏)。)


    ## 通过构造函数创建对象
    ### 构造函数创建对象的例子:
    + var xiaoming = new Object() --> var xiaoming = {};
    + var now = new Date()
    + var rooms = new Array(1,3,5) --> var rooms = [1,3,5]
    + `var isMale=/123/;` ==> `var isMale=new RegExp("123")`
    - isMale是通过RegExp构造函数创建出来的对象
    - isMale是RegExp构造函数的实例

    + 以上例子中,Object、Date、Array都是内置的构造函数

    ## 自定义一个构造函数来创建对象
    + 构造函数
    ```js
    function Person(name,age){
    this.name=name;
    this.age=age;
    }
    var p1=new Person("赵云",18)
    ```
    + 说明:`p1就是根据【Person构造函数】创建出来的对象`

    ### 构造函数的概念
    + 任何函数都可以当成构造函数
    `function CreateFunc(){ }`
    + 只要把一个函数通过new的方式来进行调用,我们就把这一次函数的调用方式称之为:构造函数的调用
    - new CreateFunc(); 此时CreateFunc就是一个构造函数(必须要有new)
    - CreateFunc(); 此时的CreateFunc并不是构造函数

    ### 关于new Object()
    + new Object()等同于对象字面量{}

    ### 构造函数的执行过程
    `var p1=new Person();`
    + 1、创建一个对象 (我们把这个对象称之为Person构造函数的实例)- `_p1 `
    + 2、创建一个内部对象,`this`,将this指向该实例(_p1)
    + 3、执行函数内部的代码,其中,操作this的部分就是操作了该实例(_p1)
    + 4、返回值:
    - a、如果函数没有返回值(没有return语句),那么就会返回构造函数的实例(p1)
    - b、如果函数返回了一个基本数据类型的值,那么本次构造函数的返回值是该实例(_p1)

    function fn(){

    }
    var f1=new fn(); //f1就是fn的实例

    function fn2(){
    return "abc";
    }
    var f2=new fn2(); //f2是fn2构造函数的实例

    - c、如果函数返回了一个复杂数据类型的值,那么本次函数的返回值就是该值

    function fn3(){
    return [1,3,5];
    //数组是一个对象类型的值,
    //所以数组是一个复杂数据类型的值
    //-->本次构造函数的真正返回值就是该数组
    //-->不再是fn3构造函数的实例
    }
    var f3=new fn3(); //f3还是fn3的实例吗?错
    //f3值为[1,3,5]


    ## 继承
    ### JS中继承的概念:
    + 通过【某种方式】让一个对象可以访问到另一个对象中的属性和方法,
    我们把这种方式称之为继承 `并不是所谓的xxx extends yyy`。

    ### 为什么要使用继承?

    + 有些对象会有相同的方法(动作、行为),而这些方法都是函数,
    如果把这些方法和函数都放在构造函数中声明就会导致内存的浪费。

    例子:
    function Person(){
    this.say=function(){
    console.log("你好")
    }
    }
    var p1=new Person();
    var p2=new Person();
    console.log(p1.say === p2.say); //false

    解析:由于say方法可能功能相似,
    但是不是同一个方法(没有指向同一块内存,会造成内存浪费)。

    解决方案:把say方法写在他们共同的(父对象)中。
    其实他们共同的父对象就可以通过Person.prototype来获取。

    结论:只要往某个构造函数的prototype对象中添加某个属性、方法,
    那么这样的属性、方法都可以被所有的构造函数的实例所共享。

    ==>这里的【构造函数的prototype对象】称之为原型对象。

    // Person.prototype是 p1 p2 p3 的原型对象
    // Person.prototype是Person构造函数的【实例】的原型对象

    猜猜看?
    Person的原型对象是谁呢?
    -->首先要知道Person的构造函数:-->Function
    -->所以Person的原型对象是:Function.prototype


    ### 继承的第一种方式:原型链继承1
    ```js
    Person.prototype.say=function(){
    console.log("你好")
    }
    ```
    + 缺点:添加1、2个方法无所谓,但是如果方法很多会导致过多的代码冗余

    ### 继承的第二种方式:原型链继承2
    ```js
    Person.prototype={
    constructor:Person,
    say:function(){
    console.log("你好");
    },
    run:function(){
    console.log("正在进行百米冲刺");
    }
    }
    ```
    + 注意点:
    + a、一般情况下,应该先改变原型对象,再创建对象
    + b、一般情况下,对于新原型,会添加一个constructor属性,从而不破坏原有的原型对象的结构

    ### 继承的第三种方式:拷贝继承(混入继承)
    + 场景:有时候想使用某个对象中的属性,但是又不能直接修改它,于是就可以创建一个该对象的拷贝
    + 实现1:
    ```js
    var source={name:"李白",age:15}
    var target={};
    target.name=source.name
    target.age=source.age;
    ```

    + 上面的方式很明显无法重用,实际代码编写过程中,很多时候都会使用拷贝继承的方式,所以为了重用,可以编写一个函数把他们封装起来:
    ```js
    function extend(target,source){
    for(key in source){
    target[key]=source[key];
    }
    return target;
    }
    extend(target,source)
    ```

    + 由于拷贝继承在实际开发中使用场景非常多,所以很多库都对此有了实现
    - jquery:$.extend

    + es6中有了对象扩展运算符仿佛就是专门为了拷贝继承而生:
    ```js
    var source={name:"李白",age:15}
    var target={ ...source }
    ```

    ### 继承的第四种方式:原型式继承
    + 场景:
    - 创建一个纯洁的对象
    - 创建一个继承自某个父对象的子对象
    + 使用方式:
    - 空对象:Object.create(null)
    -
    ```js
    var o1={ say:function(){} }
    var o2=Object.create(o1);
    ```

    ### 继承的第五种方式:借用构造函数实现继承
    + 场景:适用于2种构造函数之间逻辑有相似的情况

    function Animal(name){
    this.name=name;
    }
    function Person(name,age){
    this.name=name;
    this.age=age;
    }

    + 以上代码用借用构造函数实现
    ```js
    function Animal(name,age){
    this.name=name;
    this.age=age;
    }
    function Person(name,age,address){
    Animal.call(this,name);
    //this.name=name;
    //this.age=age;
    this.address=address;
    }
    ```

    ## 原型链

    ## 闭包
    ### 变量作用域
    + 变量作用域的概念:就是一个变量可以使用的范围
    + JS中首先有一个最外层的作用域:称之为全局作用域
    + JS中还可以通过函数创建出一个独立的作用域,其中函数可以嵌套,所以作用域也可以嵌套

    ### 作用域链
    + 由于作用域是相对于变量而言的,而如果存在多级作用域,这个变量又来自于哪里?这个问题就需要好好地探究一下了,我们把这个变量的查找过程称之为变量的作用域链
    + 简单来说,作用域链可以用以下几句话来概括:(或者说:确定一个变量来自于哪个作用域)
    - 查看当前作用域,如果当前作用域声明了这个变量,就确定结果
    - 查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明
    - 再查找上级函数的上级函数,直到全局作用域为止
    - 如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)

    + 举例1:
    ```js
    var name="张三";
    function f1(){
    var name="abc";
    console.log(name);
    }
    f1();
    ```

    + 举例2:
    ```js
    var name="张三";
    function f1(){
    console.log(name);
    var name="abc";
    }
    f1();
    ```

    + 举例3:
    ```js
    var name="张三";
    function f1(){
    console.log(name);
    var name="abc";
    }
    f1();
    ```

    + 举例4:
    ```js
    var name="张三";
    function f1(){
    return function(){
    console.log(name);
    }
    var name="abc";
    }
    var fn=f1();
    fn();
    ```

    + 举例5:
    ```js
    var name="张三";
    function f1(){
    return {
    say:function(){
    console.log(name);
    var name="abc";
    }
    }
    }
    var fn=f1();
    ```

    ### 闭包的问题
    ```js
    function fn(){
    var a=5;
    return function(){
    a++;
    console.log(a);
    }
    }
    var f1=fn();
    f1();
    f1();
    f1();
    ```

    ### 闭包问题的产生原因
    + 函数执行完毕后,作用域中保留了最新的a变量的值

    ### 闭包的应用场景
    + 模块化
    + 防止变量被破坏


    ### es6内容
    + 1、解构赋值
    + 2、函数rest参数
    + 3、箭头函数
    - 箭头函数和普通函数有哪些不同?(4点)
    + 4、对象的Object.assign
    + 5、promise
    + 6、generator
    + 7、async
    + 8、class
    + 9、module

    ### 原型
    + 原型很多人开发用不到?
    - 很多人都用es6/7/8开发,确实用的比较少
    - 如果你用es5之前的版本开发代码(IE8、IE7。。。),可能天天都要写原型
    - 理解了原型,才是理解了JS面向对象的核心,没有理解原型,你就没有理解面向对象的核心

  • 相关阅读:
    Jquery中addClass方法不起作用的解决方案
    JavaScript 下拉框 左边添加至右边
    电商网站常用放大镜特效
    jQuery 移除事件与模拟事件
    考勤管理系统V1.0.3
    js 严格模式
    service workder
    本地存储之application cache和localstorage
    Node.js内置的文件系统模块(fs)
    Node.js:OS模块
  • 原文地址:https://www.cnblogs.com/kathyhong/p/11229502.html
Copyright © 2011-2022 走看看