JavaScript中的行为委托

时间: 2018-09-03阅读: 1636标签: js知识

什么是行为委托?

简单来说就是一种设计模式,不同于传统的构造函数的“类”式设计。


在这之前先说一下原型的基本知识。
什么是原型?简单来说就是一个对象内部关联另外一个对象,本质来说就是对象与对象之间的关联;
一个对象本身没有属性或者方法会到原型对象上查找。

这里每个例子会通过构造函数,class和行为委托来不同实现,不过不会评论class,是否使用class取决于你的观点。


先看一个例子,构造函数写法

function Foo(name) {
    this.name = name;
}
Foo.prototype.age = function() {
    console.log(this.name);
};
function Fn(name) {
    Foo.call(this);
    this.name = name;
}
Fn.prototype = Object.create(Foo.prototype);
Fn.prototype.constructor = Fn.prototype;
Fn.prototype.set = function(value) {
    this.name = value;
};
var a1 = new Fn('zhangsan');
a1.age(); //zhangsan
var a2 = new Fn('lisi');
a2.set('xiaowu'); 
a2.age(); //xiaowu


class写法

class Foo {
    constructor(name) {
    this.name = name;
    }
    age() {
        console.log(this.name);
    }
}
class Fn extends Foo {
    constructor(name) {
        super();
        this.name = name;
    }
    set(value) {
        this.name = value;
    }
}
var a1 = new Fn('zhangsan');
a1.age(); //zhangsan
var a2 = new Fn('lisi');
a2.set('xiaowu'); 
a2.age(); //xiaowu


行为委托写法

var Foo = {
        const(name) {
            this.name = name;
    },
    age() {
        console.log(this.name);
    }
};
var Fn = Object.create(Foo);
Fn.set = function (value) {
    this.name = value;
};
var a1 = Object.create(Fn);
a1.const('zhangsan');
a1.age(); //zhangsan
var a2 = Object.create(Fn);
a2.set('xiaowu'); 
a2.age(); //xiaowu


可以看到比起构造函数,行为委托是通过原型链来实现的,他值关心一件事情,对象指向的关系。

再来看一个复杂一些的例子,为dom添加样式。

function Foo(value) {
    this.dom = value;
}
Foo.prototype.div = function () {
    var div = document.createElement(this.dom);
    this._dom = document.body.appendChild(div);
    return this._dom;
};
Foo.prototype.get = function () {
    return this._dom;
};
function Fn(text, cssText) {
    Foo.call(this, 'div');
    this.text = text;
    this.cssText = cssText;
}
Fn.prototype = Object.create(Foo.prototype);
Fn.prototype.constructor = Fn.prototype;
    Fn.prototype.set = function () {
    this.div();
    var div = this.get();
    div.textContent = this.text;
    Object.keys(this.cssText).forEach((name) => {
        div.style.cssText += `${name}: ${this.cssText[name]}`;
    });
};
var a = new Fn('hi', {color: 'red', "font-size": '16px'});
a.set();


class写法

class Foo {
    constructor(value) {
        this.dom = value;
    }
    div() {
        var div = document.createElement(this.dom);
        this._dom = document.body.appendChild(div);
    return this._dom;
    }
    get() {
        return this._dom;
    }
}
class Fn extends Foo {
    constructor(text, cssText) {
    super('div');
    this.text = text;
    this.cssText = cssText;
}
set() {
    super.div();
    var div = super.get();
    div.textContent = this.text;
    Object.keys(this.cssText).forEach((name) => {
        div.style.cssText += `${name}: ${this.cssText[name]}`;
    });
}
}
var a = new Fn('hi', { color: 'red', "font-size": '16px' });
a.set();


  

行为委托写法

var Foo = {
        const(value) {
        this.dom = value;
},
    div() {
        var div = document.createElement(this.dom);
        this._dom = document.body.appendChild(div);
        return this._dom;
},
    get() {
        return this._dom;
    }
};
var Fn = Object.create(Foo);
Fn.constructor = function (text, cssText) {
    this.const.call(this, 'div');
    this.text = text;
    this.cssText = cssText;
};
Fn.set = function () {
    this.div();
    let div = this.get();
    div.textContent = this.text;
    Object.keys(this.cssText).forEach((name) => {
        div.style.cssText += `${name}: ${this.cssText[name]}`;
    });
};
var a = Object.create(Fn);
a.constructor('hi', { color: 'red', "font-size": '16px' });
a.set();


 

注意点:
1.在使用行为委托时要避免标识符的重名,因为行为委托是基于原型链,不同于“类”的设计模式,可以构造函数与实例对象同时定义相同的名称的标识符。

2.两个委托对象无法互相委托,假设一个a对象关联b对象,然后b对象再关联a对象,如果两个引用了一个两个对象都不存在的属性或者方法,那么就会在原型链上形成无限循环。

来源:https://www.cnblogs.com/boses/p/9575247.html

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: https://www.fly63.com/article/detial/1045

js基础_如何理解作用域和作用域链?

作用域外,无法引用作用域内的变量;离开作用域后,作用域的变量的内存空间会被清除,比如执行完函数或者关闭浏览器,作用域与执行上下文是完全不同的两个概念。我曾经也混淆过他们,但是一定要仔细区分。JavaScript代码的整个执行过程,分为两个阶段,代码编译阶段与代码执行阶段。

js词法作用域和作用域的理解_什么是javascript词法作用域?

JavaScript引擎在代码执行前会对其进行编译:第一步编译阶段,第二步运行阶段。词法作用域:定义在词法阶段的作用域,即书写代码时函数声明的位置决定的。词法分析器处理代码时会保持作用域不变

适配器在JavaScript中的体现

适配器设计模式在JavaScript中非常有用,在处理跨浏览器兼容问题、整合多个第三方SDK的调用,都可以看到它的身影。适配器模式是一种软件设计模式,允许从另一个接口使用现有类的接口。它通常用于使现有的类与其他类一起工作,而无需修改其源代码。

js中return关键词的作用_return的用法详解

return从字面意思来看就是返回,官方定义return语句将终止当前函数并可以返回当前函数的值; 也就是说return后面可以跟一个value,也就是说可以跟javascript中的任何数据类型

基于规则评分的密码强度检测算法分析及实现(JavaScript)

用正则表达式做用户密码强度的通过性判定,过于简单粗暴,不但用户体验差,而且用户帐号安全性也差。那么如何准确评价用户密码的强度,保护用户帐号安全呢?本文分析介绍了几种基于规则评分的密码强度检测算法

数字在JavaScript中是如何编译的

JavaScript中的所有数字都是浮点数。这篇博客文章解释了这些浮点数如何在64位二进制内部表示。浮点数并不一定等于小数,定点数也并不一定就是整数。所谓浮点数就是小数点在逻辑上是不固定的,而定点数只能表示小数点固定的数值

js常见知识点整理总结

一些常用的JavaScript 知识点整理,包括:两个函数是否等价、NaN是什么?它是什么类型?如何检测一个变量是否是NaN?作用域相关问题?js小数计算不准确的bug,js算法/思路相关,js类型强制转换

Js常用基础算法

冒泡排序;插入排序 过程就像你拿到一副扑克牌然后对它排序一样;快速排序;回文字符串;翻转字符串;字符串中出现最多次数的字符;数组去重;二分查找

JS 超类和子类

看到javascript高级程序设计的面向对象章节看到超类与子类这个概念词,不懂上度娘查了才知道是怎么一回事。说到超类与子类,就不得不提起原型模式,原型对象,原型链与原型链继承了

原生js实现数组随机排列(数组乱序)的方法.【快速洗牌算法】

在开发中遇到这样的问题,需要将一组已知数组的顺序打乱,按照以前和现在的做法,总结了以下方法。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!