[[Prototype]]机制
[[Prototype]] 机制: JavaScript 中这个[[Prototype]] 机制的本质就是对象之间的关联关系。
SonA未重写父类方法,所以.say()执行的是父类中的say方法
SonB重写了父类方法,所以.say()执行的是重写后的say方法

class Father {
id = '';
constructor(id) {
this.id = id;
}
say() {
return this.id;
}
}
class SonA extends Father {
label = '';
constructor(id, label) {
super(id);
this.label = label;
}
}
class SonB extends Father {
label = '';
constructor(id, label) {
super(id);
this.label = label;
}
say() {
return this.label;
}
}
const sonA = new SonA('aaa', 'Lee');
const sonB = new SonB('bbb', 'Tom');
console.log(sonA, sonB); // SonA {id: 'aaa', label: 'Lee'} SonB {id: 'bbb', label: 'Tom'}
console.log(sonA.say(), sonB.say()); // aaa Tom
以委托行为方式来思考上述代码
以下的编码格式风格称为
“对象关联”(OLOO, objects linked to other objects)

const Father = {
setData(id) { this.id = id },
say() { return this.id }
}
const sonA = Object.create(Father);
sonA.setDataA = function (id, label) { this.setData(id); this.label = label; }
const sonB = Object.create(Father);
sonB.setDataB = function (id, label) { this.setData(id); this.label = label; }
sonB.say = function () { return this.label; }
sonA.setDataA('aaa', 'Lee');
sonB.setDataB('bbb', 'Tom');
console.log(sonA, sonB); // {id: 'aaa', label: 'Lee', setDataA: ƒ} {id: 'bbb', label: 'Tom', setDataB: ƒ, say: ƒ}
console.log(sonA.say(), sonB.say()); // aaa Tom
对象关联特点:
id 和 label 数据成员都是直接存储在 sonA sonB 上(而不是 Father)say方法this.setData(id);会先从本身开始像原型链上查找此方法JavaScript创建UI控件比如使用
ES6类的class形式创建一个Button UI组件 - (面向对象的UI控件创建)
// 控件基类
function Widget(width, height) {
this.width = width || 50;
this.height = height || 50;
this.$elem = null;
}
// 渲染方法
Widget.prototype.render = function ($where) {
if (this.$elem) {
this.$elem.css({
width: this.width + "px",
height: this.height + "px"
}).appendTo($where);
}
};
// Button控件
function Button(width, height, label) {
// 调用“super”构造函数
Widget.call(this, width, height);
this.label = label || "Default";
this.$elem = $(").text(this.label);
}
// 让 Button“继承”Widget
Button.prototype = Object.create(Widget.prototype);
// 重写 render(..)
Button.prototype.render = function ($where) {
//“super”调用
Widget.prototype.render.call(this, $where);
this.$elem.click(this.onClick.bind(this));
};
// Button点击事件
Button.prototype.onClick = function (e) {
alert(`Button ${this.label} clicked!`);
};
$(document).ready(function () {
var $body = $(document.body);
var btn1 = new Button(125, 30, "Hello");
var btn2 = new Button(150, 40, "World");
btn1.render($body);
btn2.render($body);
});
// UI组件基类
class Widget {
/**
* 初始化控件
* @param {number} width 宽度
* @param {number} height 高度
* @returns {undefined}
*/
constructor(width, height) {
this.width = width || 50;
this.height = height || 50;
this.$elem = null;
}
/**
* 渲染控件
* @param {Element} $where 父控件
* @returns {undefined}
*/
render($where) {
if (this.$elem) {
this.$elem.css({
width: this.width + "px",
height: this.height + "px"
}).appendTo($where);
}
}
}
// Button组件
class Button extends Widget {
/**
* 初始化控件
* @param {number} width 宽度
* @param {number} height 高度
* @param {string} label 控件内容
* @returns {undefined}
*/
constructor(width, height, label) {
// 调用父类方法
super(width, height);
this.label = label || "Default";
this.$elem = $(").text(this.label);
}
/**
* 渲染控件 重写父类方法
* @param {Element} $where 父控件
* @returns {undefined}
*/
render($where) {
super.render($where);
this.$elem.click(this.onClick.bind(this));
}
// 点击事件
onClick(e) {
alert(`Button ${this.label} clicked!`);
}
}
// 添加UI组件
$(document).ready(function () {
var $body = $(document.body);
var btn1 = new Button(125, 30, "Hello");
var btn2 = new Button(150, 40, "World");
btn1.render($body);
btn2.render($body);
});
// UI控件基类
var Widget = {
init: function (width, height) {
this.width = width || 50;
this.height = height || 50;
this.$elem = null;
},
insert: function ($where) {
if (this.$elem) {
this.$elem.css({
width: this.width + "px",
height: this.height + "px"
}).appendTo($where);
}
}
};
// Button继承自Widget
var Button = Object.create(Widget);
// Button控件初始化
Button.setup = function (width, height, label) {
// 委托调用
this.init(width, height);
this.label = label || "Default";
this.$elem = $(").text(this.label);
};
// Button控件创建
Button.build = function ($where) {
// 委托调用
this.insert($where);
this.$elem.click(this.onClick.bind(this));
};
// Button点击事件创建
Button.onClick = function (e) {
alert(`Button ${this.label} clicked!`);
};
$(document).ready(function () {
var $body = $(document.body);
var btn1 = Object.create(Button);
btn1.setup(125, 30, "Hello");
var btn2 = Object.create(Button);
btn2.setup(150, 40, "World");
btn1.build($body);
btn2.build($body);
});

<form action="#" onsubmit="return false;">
<p><label for="login_username">用户名:<input id="login_username" type="text">label>p>
<p><label for="login_password">密码:<input id="login_password" type="password">label>p>
<button id="login_btn" type="submit">登录button>
form>
{
"code": 200,
"data": {
"name": "PLee",
"age": 18
},
"msg": "操作成功"
}
// 基类
class Controller {
errors = null;
constructor() {
this.errors = [];
}
// 获取得到的数据
getData(title, data) {
console.log(title, data);
}
// 成功
success(res) {
this.getData("【Success】", res);
}
// 失败
failure(err) {
this.errors.push(err);
this.getData("【Error】", err);
}
}
// 登录
class LoginController extends Controller {
constructor() {
super();
}
// 获取用户名
getUser() {
return document.getElementById("login_username").value;
}
// 获取密码
getPassword() {
return document.getElementById("login_password").value;
}
// 验证 用户名/密码
validateEntry(user, pw) {
user = user || this.getUser();
pw = pw || this.getPassword();
if (!user) {
return this.failure("请输入用户名!");
}
if (!pw) {
return this.failure("请输入密码!");
}
// 如果执行到这里说明通过验证
return true;
}
// 重写基础的 failure()
failure(err) {
super.failure(err);
}
}
// 认证
class AuthController extends Controller {
login = null;
constructor(login) {
super();
this.login = login;
}
// 数据请求
server(url, data) {
return $.ajax({ url, data });
}
// 检查认证
checkAuth() {
var user = this.login.getUser();
var pw = this.login.getPassword();
if (this.login.validateEntry(user, pw)) {
this.server("/check-auth.json", { user, pw })
.then(res => this.success(res))
.fail(err => this.failure(err));
}
}
// 成功
success(res) {
super.success(res);
}
// 失败
failure(err) {
super.failure(err);
}
}
$(document).ready(function () {
$('#login_btn').click(function (e) {
var auth = new AuthController(new LoginController());
auth.checkAuth();
})
})