美文网首页
JS模块_require,new机制_this机制

JS模块_require,new机制_this机制

作者: 大猫城堡 | 来源:发表于2019-01-14 22:32 被阅读0次

    代码模块,导出对象

    我们所有的代码不能都写到一个文件里面,如何分开文件? js--> 模块机制;

    js 加载代码的 require()

    step1: 加载指定的js代码,并执行;

    require("./utils")
    

    // 如果js代码已经被加载进来了,是不会执行的;

    require("./utils")
    

    // require 返回值, 返回加载进来的代码的

    module.exports 所指向的对象;
    

    // 多次require同一个模块,都回返回这个

    module.exports;
    var utils = require("./utils");
    console.log(ret); 
    

    返回的是一个 {},因为你还没有指定module.exports导出的对象;

    console.log(ret(3, 4));
    //调用函数
    console.log(utils.add(3, 4));
    
    总结一下:

    1: js里面代码可以放在不同的文件里,称为代码模块;
    2: 一个模块需要引用其它模块代码的时候使用 require;
    3: require:
    (1) 如果是第一次调用,那么就加载,执行脚本;
    (2) 每个代码模块由module.exports 导出的对象;
    (3) 每次require的时候,都返回module.exports;
    (4) 如果不是第一次执行,那么直接返回module.exports;

    代码规范

    一般我们会用和代码名字同名的变量,来接住require的返回值;

    var test = require("./test");
    console.log(test);
    

    this 机制

    用法

    1:function.call(this, param1, param2);
    2:表.函数名(参数):
    (1) 在函数里面 有一个this对象,指的是外面的表;
    (2) 如果外面没有表,那么this为undefine;
    (3) 函数.bind(数据对象),会产生一个新的函数对象,调用这个函数的this,就是外面bind的对象;

    显式和隐式传递 this
    function my_func(lhs, rhs) {
        console.log(this); // 使用this;
        console.log(lhs, rhs)
    } 
    
    // 函数调用, this,可能是一个不确定的值;
    my_func(3 , 4); 
    // 函数.call: 显示的传递this。注意:传的是第一个逗号前面的,后面的“3, 4”没有被传
    // 最好执行返回函数结果
    my_func.call({name: "blake"}, 3, 4);
    
    // 表.key 来隐式的传递this;
    var tools = {
        my_func: my_func,
    }
    // 表.函数key() --> this就传为表,在这里为tools这个表
    tools.my_func(3 ,4); 
    
    强制绑定 this, 最高优先级
    // 函数.bind, 不会改变原来的函数对象的this,而是会产生一个新的函数对象,bind好了this
    //
    var new_func = my_func.bind({name: "blake"}); 
    new_func(3 ,4);
    
    tools.my_func = new_func;
    tools.my_func(3, 4); 
    
    my_func(3, 4) 
    
    call 与 bind 有什么区别呢?

    bind最牛的地方是什么?是绑定this的时候,
    不是由调用者来决定

    //显示的传递 this 也没用
    new_func.call({name: "blake_test"}, 3, 4)
    
    总结
    1. 在函数里面访问this, this是什么是由调用的环境来决定的, 是不确定的,我们一般不使用;
    2. 显式的传递this, 函数.call(this对象, 参数)
    3. 隐式的传递this, 表.key_函数(参数), this--> 表。注意:“key_函数”意思是key指向的一个函数
    4. 强制bind this, 函数.bind(this对象): 产生一个强制bind this的新的函数对象; bind 优先级别是最高的;

    new 机制 与 构造函数

    如何构造“类”,并用“类”构造出来实例?

    new 机制重点:new 对象下的 this 是表
    用法

    1: js 构造函数: 普通的函数(参数),一般和类的名字是一样的;

    2: new +构造(参数1, 参数2....);
    (1)先创建一个{}对象;
    (2)将这个新对象绑定到函数里面的this;
    (3)构造函数对象的表 prototype 复制给新表 proto
    (4) 返回新创建的对象;

    3: 表.函数调用搜索顺序,现在key, value里查找,再到proto里找;

    function person(name, age) {
        this.name = "chengbo";
        this.age = "22";
    }
    
    var obj = new person
    console.log(obj); //person { name: 'chengbo', age: '22' }
    
    function person(name, age) {
            //对表进行初始化,向表里添加 key 和 value;
        this.name = name;
        this.age = age;
    }
    
    // 机制1 每一个函数对象都有一个叫做“prototype”的表;
    //person.prototype,“函数.表”意思是这个表的名字,也叫函数person有个成员叫做prototype
    
    console.log(person.prototype);
    
    //1. 表可以携带很多对象和value
    //2. 往person.prototype这个表里添加key, 这个key是个函数对象
    person.prototype.get_age = function() {
        return this.age;
    }
    
    // 机制2: new 关键字 + 函数(参数) 做了下面4个事情
    
    // step1: 创建了一个新的表 {};
    // step2: 会把创建的新的表通过 this 显示传递,并调用构造函数person
    // 进入到构造函数person之后,“person构造函数里面的this”就是刚新建的表“.__proto__”。
    // step3: 构造函数里面 prototype 这个表赋值到新表“.__proto__”里
    // 新表“.__proto__”完全复制了person.prototype这个表里面的内容
    // step4: “返回”这个新的表;
    
    // new 函数起的作用是构造出来 一个表的实例,或者说同一个类型的不同的对象
    // new 后面跟着的这个函数叫做构造函数,可以在构造函数里初始化表对象;
    
    var blake = new person("Blake", 34);
    console.log(blake);
    
    var tom = new person("tom", 34);
    console.log(tom);
    
    var xiaoming = new person("xiaoming", 12);
    console.log(xiaoming);
    
    // __proto__: get_age--> 函数对象;
    console.log(xiaoming.__proto__); 
    // 新表里面会有一个.__proto__的key,同时.__proto__也是一个表,复制了person.prototype表里的key和value
    
    搜索机制;
    // 当我们在一个表里使用key的时候,
    // 首先我们会在表里面找, 如果找到就直接使用这个key,所对应的value;
    // 如果没有找到,我们会去__proto__这个里面找,找到就用;
    // 进入函数的时候,如果没有强制绑定this,就会根据隐式的调用规则。
    //把xiaoming---> this get_age
    
    var ret = xiaoming.get_age()
    ret = blake.get_age();
    console.log(ret);
    
    new 机制做的事情
    function new_person(name, age) {
        // step1: 在函数里创建一个新的表
        var instance = {};
        // step2: 通过显式的传递this,把instance传给函数person,就会有成员
        person.call(instance, name, age);
        // step3: instance加一个成员__proto__,这个成员是一个新的表,所以表里面可以有表
        instance.__proto__ = {};
        // step4: 将person里面的prototype这个表复制过来;
        for(var key in person.prototype) {
            instance.__proto__[key] = person.prototype[key];
        }
        // step5: 返回实例instance
        return instance;
    }
    
    
    var xiaohong = new_person("xiaohong", 12);
    console.log(xiaohong);
    
    ##搜索机制用法
    // step1 xiaohong 这个表里面找;
    // step2 如果没找到,__proto__表里找--> 找到;
    ret = xiaohong.get_age();
    console.log(ret);
    
    var xiaotian = {
        name: "blake",
        age: 30,
    
        __proto__: {
            get_age: person.prototype.get_age,
        },
    }
    
    ret = xiaotian.get_age()
    console.log(ret);

    相关文章

      网友评论

          本文标题:JS模块_require,new机制_this机制

          本文链接:https://www.haomeiwen.com/subject/dtrsdqtx.html