本文通过具体代码实例,深入解析JavaScript中的原型克隆机制。详细演示了如何利用构造函数F()实现对象浅克隆,并探讨了对克隆后的对象添加属性(如books数组)及方法的技巧。同时对比了直接修改子对象与重新赋值的不同方式,帮助开发者理解对象引用与属性管理的细节。
JavaScript原型克隆与对象属性操作详解
本文通过具体代码实例,深入解析JavaScript中的原型克隆机制。详细演示了如何利用构造函数F()实现对象浅克隆,并探讨了对克隆后的对象添加属性(如books数组)及方法的技巧。同时对比了直接修改子对象与重新赋值的不同方式,帮助开发者理解对象引用与属性管理的细节。
<script type="text/javascript">
/* 克隆原型得到对象 */
function clone(object) {
function F() {}
F.prototype = object;
return new F;
}
var Person = {
name: 'default name',
getName: function() {
return this.name;
}
};
var reader = clone(Person);
console.log(reader.getName()); // This will output 'default name'.
reader.name = 'John Smith';
console.log(reader.getName()); // This will now output 'John Smith'.
/* Author Prototype Object. */
var Author = clone(Person);
Author.books = []; // 书数组
Author.getBooks = function() {
return this.books;
}
var author = [];
author[0] = clone(Author);
author[0].name = 'Dustin Diaz';
author[0].books = ['JavaScript Design Patterns'];
author[1] = clone(Author);
author[1].name = 'Ross Harmes';
author[1].books = ['JavaScript Design Patterns','PHP','Mysql'];
console.log(author[0].getName());
console.log(author[0].getBooks());
console.log(author[1].getName());
console.log(author[1].getBooks());
</script>
运行上述代码后的输出结果如下所示。

在此处使用console.log进行调试比使用alert更为高效。因为alert对话框无法一次性展示复杂数据结构的全部信息,必须逐个弹出查看,而console.log可以直接在控制台查看完整对象内容。
JavaScript中数组的定义方式同样具有其独特之处,值得注意。
接下来进行更复杂的场景测试,即在克隆后的对象上进一步扩展属性和方法。
<script type="text/javascript">
/* 克隆原型得到对象 */
function clone(object) {
function F() {}
F.prototype = object;
return new F;
}
var Person = {
name: 'default name',
getName: function() {
return this.name;
}
};
var Author = clone(Person);
Author.books = []; // 书数组
Author.getBooks = function() {
return this.books;
}
var authorClone = clone(Author);
console.log(authorClone.name); // string 'default name'.
authorClone.name = 'new name'; // 重新赋值
console.log(authorClone.name); // Now linked to the primative authorClone.name, which
// is the string 'new name'.
console.log(Author.getName()); // 没有改变,任然是 'default name'
console.log(Author.getBooks()); // 空的
authorClone.books.push('new book'); // Author被改了
authorClone.books.push('new new book'); // Author被改了
console.log(Author.getBooks()); // array 'new book'
console.log(authorClone.getBooks()); // array 'new book'
authorClone.books = []; // 定义了属于自己的books数组
authorClone.books.push('new book2'); // We are now modifying that new array.
authorClone.books.push('new book3');
authorClone.books.push('new book4');
console.log(authorClone.getBooks());
console.log(Author.getBooks());
var CompoundObject = {
string1: 'default value',
childObject: {
bool: true,
num: 10
},
getChild: function() { // 返回对象Object
return this.childObject;
}
}
var compoundObjectClone = clone(CompoundObject);
compoundObjectClone.childObject.num = 5; // 不好的方式
compoundObjectClone.childObject = { // 好一点的方式
bool: true,
num: 5
};
console.log(compoundObjectClone.getChild());
</script>
扩展操作后的运行结果如下。

如需了解更多JavaScript相关知识,建议参考本站系列教程,包括《JavaScript常用函数技巧汇总》、《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。
希望本文提供的关于JavaScript程序设计的实例分析能对读者有所帮助。