«

JavaScript中的Mixin是什么

时间:2024-5-16 13:07     作者:韩俊     分类: Javascript


这篇文章主要介绍“JavaScript中的Mixin是什么”,在日常操作中,相信很多人在JavaScript中的Mixin是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”JavaScript中的Mixin是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    类的出现最终使

    JavaScript
    非常容易使用继承语法,
    JavaScript
    类比大多数人意识到的更强大,它是构建真正的
    mixins
    的良好基础。

    什么是 Mixin

    JavaScript
    中,把不同类的行为集中到一个类是一种常见的模式,虽然
    ES6
    没有显示支持多类继承,但通过现有特性可以轻松地模拟这种行为。

    Object.assign()
    方法是为了混入对象行为而设计的,只有在需要混入类的行为时才有必要自己实现混入表达式,如果只是需要混入多个对象的属性,那么使用
    Object.assign()
    就可以了。

    在集成或者实例化时,

    JavaScript
    的对象机制并不会自动执行复制行为,简单来说,在
    JavaScript
    中只有对象,并不存在可以被实例化的类,一个对象并不会被复制到其他对象,它们会被关联起来。

    在其他语言中类表现出来的都是复制行为,因此

    JavaScript
    开发者也想出了一个方法来模拟类的复制行为,这个方法就是混入。

    那么在接下来的内容中我们会看到两种类型的混入,它们分别是显示混入和隐式混入。

    显示混入

    首先我们举一个简单的例子,在这里我们实现一个

    mixin(...)
    函数,这个功能在许多库和框架中被称为
    extend
    ,具体代码如下所示:

    function mixin(source, target) {
      for (const key in source) {
        if (!(key in target)) target[key] = source[key];
      }
    
      return target;
    }

    接下来我们实现一个 

    foo
     类 和 
    bar
     类,然后将两个类进行 
    mixin
    ,生成一个新的类,具体代码如下所示:

    const bar = {
      technical: function () {
        console.log("跳");
      },
      moment: function () {
        this.technical();
      },
    };
    
    const foo = {
      nickname: "xun",
      hobby: "nba",
      age: 18,
      moment: function () {
        bar.moment.call(this);
      },
    };
    
    console.log(mixin(bar, foo));

    现在返回的新对象中就有了一份

    bar
    对象的属性和函数的副本了,从技术角度来说,函数实际上没有被复制,复制的是函数引用。

    所以返回的新对象中的属性

    thchnical
    方法只是从
    bar
    中复制过来的对与
    moment
    函数的引用,相反
    moment()
    就是直接从
    bar
    中复制了值 1。

    foo
    已经有了
    moment
    方法,所以这个属性引用并没有被
    mixin
    重写,从而保留了
    foo
    中定义的同名方法,实现了子类对子类属性的重写。

    显示混入模式的一种变体被称为

    寄生继承
    ,它既是显示的又是隐式的,具体代码如下所示:

    function Foo() {
      this.nickname = "moment";
    }
    
    Foo.prototype.ignition = function () {
      console.log("小黑子");
    };
    
    Foo.prototype.小黑子 = function () {
      this.ignition();
      console.log("叼毛");
    };
    
    // 寄生类
    function Bar() {
      const foo = new Foo();
    
      foo.age = 18;
    
      const 你小子 = foo.小黑子;
    
      foo.小黑子 = function () {
        你小子.call(this);
        console.log("不是所有的牛奶都是特仑苏");
      };
    
      return foo;
    }
    
    const result = new Bar();
    console.log(result);

    该代码的最终输出结果如下所示:

    就像你看到的一样,首先我们复制一份 

    Foo
     父类对象的定义,然后混入子类独享的定义。

    隐式混入

    隐式混入示例代码如下所示:

    const something = {
      cool: function () {
        this.greeting = "hello";
        this.count = this.count ? this.count + 1 : 1;
      },
    };
    
    console.log(something.cool()); // undefined
    console.log(something.greeting); // hello
    console.log(something.count); // 1
    
    const another = {
      cool: function () {
        something.cool.call(this);
      },
    };
    
    console.log(another.cool()); // undefined
    console.log(another.greeting); // hello
    console.log(another.count); // 1

    在上面代码中通过在构造函数调用或者方法调用中使用

    something.cool.call(this)
    ,让我们实际上
    借用
    了函数
    something.cool()
    函数并在
    another
    的上下文中调用了它(通过
    this
    指向),最终的结果是
    something.cool()
    函数中的赋值操作都会应用在
    another
    对象上而不是
    something
    对象上。

    因此我们把

    something
    的行为混入到了
    another
    中。

    标签: javascript

    热门推荐