根据道格拉斯·克罗克福德(Douglas Crockford)的书“ JavaScript:好的零件”的定义,耐用的对象是一种功能风格的对象,其所有方法均不使用 this < / em>或 that 。请查看以下示例:
这是耐用对象的示例:
var request = HttpWebRequest.CreateHttp(url);
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1";
request.Method = "HEAD";
using (var response = await request.GetResponseAsync())
{
var length = response.ContentLength;
}
这是非耐用对象的示例:
const MyObj = function()
{
const myObj = BaseObject();
const inp = create( "input" );
inp.type = "checkbox";
const txt = doc.createTextNode("");
myObj.control = create( "label" );
myObj.control.appendChild( inp );
myObj.control.appendChild( txt );
myObj.setState = state => inp.checked = state;
myObj.getState = () => inp.checked;
myObj.setCaption = cap =>
{
txt.textContent = cap;
}
return myObj;
}
我想知道是否有耐用的物品(无此物品)是一种好习惯。重要因素包括我们的JavaScript代码的性能,安全性,可伸缩性和灵活性。
答案 0 :(得分:0)
您的例子都不是好例子。
它们两者每次都为方法分配内存。
您的myObj
开头有BaseObject
的方法,字段。但是在您说:allocate memory for setState method and attach to instance
prototypes
来了:
MyObj.prototype.setState = state => this._state = state;
MyObj.prototype.getState = () => Object.assign({}, this._state);
原型是静态对象,只分配一次并关联到类的实例。
现在让我们从您的代码中制作组件(只是为了好玩):
class Component
{
constructor(initialState) {
this._state = initialState ? initialState : {};
this._masterNode = document.createElement(this.constructor.name);
this._eventListeners = {};
}
createElement(tagName, attributes = {}, onStateChange) {
const element = document.createElement(tagName);
Object.assign(element, attributes);
if (onStateChange) {
this.on('stateChanged', (newState) => {
onStateChange(newState, element);
});
}
return element;
}
createInput(name, type, onStateChange) {
return this.createElement('input', {name, type}, onStateChange);
}
createLabel(labelFor, onStateChange) {
return this.createElement('label', {for: labelFor}, onStateChange);
}
createTextNode(text, onStateChange) {
const textNode = document.createTextNode(text);
if (onStateChange) {
this.on('stateChanged', (newState) => {
onStateChange(newState, textNode);
});
}
return textNode;
}
appendChild(element) {
this._masterNode.appendChild(element);
}
setState(state) {
Object.assign(this._state, state);
this.emit('stateChanged', this._state);
}
getState() {
return Object.assign({}, this._state);
}
on(eventName, listener) {
if (!this._eventListeners[eventName]) this._eventListeners[eventName] = [];
this._eventListeners[eventName].push(listener);
}
emit(eventName, payload) {
if (!this._eventListeners[eventName]) return;
console.log(eventName, payload);
this._eventListeners[eventName].forEach(method => {
method(payload);
});
}
appendTo(container) {
container.appendChild(this._masterNode);
}
}
const form = new Component();
// create label
const label = form.createLabel('termsAndConditions');
// create checkbox with state listener
const checkbox = form.createInput('something', 'checkbox',
(newState, element) => {
if (newState.agreedWithTC === true) {
element.checked = true;
return;
}
element.checked = false;
});
// operating with state on click by checkbox
checkbox.onclick = () => {
if (checkbox.checked) {
form.setState({agreedWithTC: true});
return;
}
form.setState({agreedWithTC: false});
};
// append checkbox to label
label.appendChild(checkbox);
const textNode = form.createTextNode('Agree with T&C',
(newState, element) => {
textNode.textContent = textNode.textContent.replace('(agreed)', '').replace('(not agreed)', '');
if (newState.agreedWithTC === true) {
textNode.textContent += ' (agreed)';
return;
}
textNode.textContent += ' (not agreed)';
});
// create text node and append it to label
label.appendChild(textNode);
// append label to form
form.appendChild(label);
// append overall component instance to container
form.appendTo(document.getElementById('container'));
setInterval(() => {
form.setState({agreedWithTC: !form.getState().agreedWithTC});
}, 1000);
<div id="container"></div>