拷贝和继承有什么区别?

简单理解,huluoyang.gitcafe.io和hexo.com的关系就是继承,
hexo提供了博客的的网站架构、主题和插件等,
我不需要重新发明轮子,直接继承hexo就拥有了hexo的所有功能。
而Typecho与WordPress的关系就是拷贝,前者基于后者做了一个一模一样的博客软件。
当然Typecho发展得如何,与WordPress就毫无关系了。
拷贝就是我拥有你的功能,并且与你无关。
继承就是我拥有你的功能,而且与你密不可分。
一个是白手起家,一个是富二代创业,两者各有利弊。

什么东西才需要拷贝?

如果是原始数据类型,那没有什么值得拷贝的,直接赋值一个新的变量即可。
如果是引用数据类型,譬如对象或数组、或者我们经常用到的json,那才需要拷贝。

拷贝又分为浅拷贝和深拷贝

关于这点业内一直有不同的认识。
有人认为浅拷贝就是仅仅拷贝最外层部分,深层部分不拷贝。
这种拷贝速度来得快,所以也经常被称为山寨。
譬如拷贝Facebook模式的网站这么多,绝大部分只能拷贝Facebook模式的外表,而拷贝不了其精髓。
而小米就不仅仅是拷贝苹果的模式,它深得苹果的精髓,发展成自己的品牌。
而在编程界,浅拷贝就是纯拷贝,和原创死死地绑定在一起,没有自己丝毫的创新。
而深拷贝,不仅拷贝原创,而且和原创分离开来,有自己的创新。
关于这点,网上很多技术文章的认识都是错误的,譬如:http://hovertree.com/h/bjaf/ehq4no5x.htm
而正确的解释可以参考:http://www.cnblogs.com/rubylouvre/archive/2010/03/26/1696600.html
在我们的日常编程中,从github上clone一个项目时,如果加上–depth=1就是浅拷贝,不加就是深拷贝。

//shadowCopy 浅拷贝
var shadowCopy = function(result,source){
for(var key of source){
result[key] = source[key];
}
return result;
}

浅拷贝对于depth=1的对象是够用的,但对于depth>=2的对象来说会有问题。

// deepCopy  深拷贝
var deepCopy = function(result,source){
for(var key of source){
var copyType = Object.prototype.toString.call(source[key]);
if(copyType === "[object Array]"){
result[key] = arguments.callee(result[key] || [], source[key]);
}else if(copyType === "[object Object]"){
result[key] = arguments.callee(result[key] || {}, source[key]);
}else{
result[key] = source[key];
}
}
return result;
}

我们采用了for of的方式来遍历对象,减少了原型属性的遍历,大幅提升了性能。
浅拷贝足以满足我们日常开发中的绝大部分场景,
例如:

Array.prototype.slice.call(document.getElementsByTagName('*')) //也是浅拷贝

深拷贝中应用到了递归,使用请万分谨慎。