js 实现对象的混合与克隆效果,带完整版解析代码[helpers.js]
前言:
本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽。
本篇文章为您分析一下原生JS写淘宝无缝轮播图效果
对象混合
页面中如下需求
var obj1 = {
x: 1,
y: "a"
}
var obj2 = {
x: "b",
o: 6
}
我们要把这两个对象混合成一个
形成如下结构:
// 将obj2混合到obj1中
obj = {
x: "b",
y: "a",
o: 6
}
/**
* ES5之前的版本
* 对象的混合
* @param {Object} obj1
* @param {Object} obj2
*/
function mixin(obj1, obj2){
// 第一步: 创建一个对象
var newObj = {};
// 第二步: 循环obj2中的对象
for(var prop in obj2){
// 第三步: 将obj2中的属性添加到新创建爱对象中
newObj[prop] = obj2[prop];
}
// 第四步: 循环obj1中的对象
for(var prop in obj1){
// 第五步: 看看obj1中的属性在不在obj2中,如果不在就将他加入的新的对象中
if(!(prop in obj2)){
newObj[prop] = obj1[prop];
}
}
// 最后返回这个新的对象
return newObj;
}
/**
* ES6版本
* 对象的混合
* @param {Object} obj1
* @param {Object} obj2
*/
// function mixin(obj1, obj2){
// return Object.assgin({},obj1,obj2);
// }
var obj = mixin(obj1, obj2);
console.log(obj);
对象克隆
页面中如下需求
var obj = {
x: "123",
y: 456,
objSon: {
c: "a"
}
}
var newObj = clone(obj);
// 要求实现newObj中有obj的所有属性
// 并且newObj.objSon !== obj.objSon;
function clone(obj) {
var newObj = {};
for (var prop in obj) {
newObj[prop] = obj[prop];
}
}
var obj = 123;
因为我们在function中创建了一个对象
如果obj是一个字符串呢?
var obj = "abcdefg";
var obj = [12,35,65,87,1,3];
并且length属性还得不到
图片
我们刚刚写的代码(只是假设他是普通对象,还不是数组对象,数组本身也是对象嘛)就不足以完成一个完整的克隆函数
因此,我们要进行判断
function clone(obj) {
if (Array.isArray(obj)) { // 如果他是一个数组
return obj.slice(); // 复制数组
} else if (typeof obj === "object") { // 如果他是一个普通对象
var newObj = {}; // 定义一个对象
for (var prop in obj) { // 循环obj
newObj[prop] = obj[prop]; // 添加属性
}
return newObj; // 返回
} else { // 函数、原始类型
return obj; // 直接返回
}
}
var newObj1 = clone(obj1);
var newObj2 = clone(obj2);
var newObj3 = clone(obj3);
var newObj4 = clone(obj4);
但是并没有完整
如果obj的属性也是一个对象呢?
var obj = {
x: "123",
y: 456,
subObj: {
a: "abc"
}
}
但是它里面的subObj属性的地址是一样的
如果我们给newObj.subObj.a ==="XXX";赋值了。
他会导致:obj.subObj.a也跟着改变。
所以我们把目前我们写的这种方式叫做 [浅度克隆]
还有一种克隆叫 [深度克隆] 就是要对他属性做深度处理
因此这个函数还需要一个参数来判断他是否需要深度克隆
function clone(obj, deep) {
if (Array.isArray(obj)) { // 如果他是一个数组
return obj.slice(); // 复制数组
} else if (typeof obj === "object") { // 如果他是一个普通对象
var newObj = {}; // 定义一个对象
for (var prop in obj) { // 循环obj
if (deep){
// 如果是深度克隆的话,我们把这个属性的值再克隆一遍【递归】
newObj[prop] = this.clone(obj[prop], deep);
}else {
newObj[prop] = obj[prop]; // 添加属性
}
}
return newObj; // 返回
} else { // 函数、原始类型
return obj; // 直接返回 【递归的终止条件】
}
}
// 再传入第二个参数
var newObj = clone(obj, true);
function clone(obj, deep) {
if (Array.isArray(obj)) { // 如果他是一个数组
if(deep){ // 深度克隆
var newArr = []; //定义一个空数组
for(var i = 0; i< obj.length; i++){ // 循环obj的每一项
newArr[i].push(clone(obj[i],deep)); // pun数组
}
}else {
return obj.slice(); // 复制数组
}
} else if (typeof obj === "object") { // 如果他是一个普通对象
var newObj = {}; // 定义一个对象
for (var prop in obj) { // 循环obj
if (deep){
// 如果是深度克隆的话,我们把这个属性的值再克隆一遍【递归】
newObj[prop] = this.clone(obj[prop], deep);
}else {
newObj[prop] = obj[prop]; // 添加属性
}
}
return newObj; // 返回
} else { // 函数、原始类型
return obj; // 直接返回 【递归的终止条件】
}
}
完整插件代码
对象混合
this.myPlugin.mixin = function (obj1, obj2) {
return Object.assign({}, obj1, obj2);
// // 建立一个新对象
// var newObj = {};
// // 进行 for in 循环
// for (var prop in obj2) {
// newObj[prop] = obj2[prop];
// }
// // 找到obj1中有但是obj2中没有的属性
// for (var prop in obj1) {
// if (!(prop in obj2)) {
// newObj[prop] = obj1[prop]
// }
// }
// return newObj;
}
对象克隆
/**
* 克隆一个对象
* @param {Array} obj 对象
* @param {boolean} deep 是否深度克隆
*/
this.myPlugin.clone = function (obj, deep) {
if (Array.isArray(obj)) {
if (deep) { //深度克隆
var newArr = [];
for (var i = 0; i < obj.length; i++) {
newArr.push(this.clone(obj[i], deep));
}
return newArr;
}
else { // 浅度克隆
return obj.slice(); //复制数组
}
}
else if (typeof obj === "object") {
var newObj = {};
for (var prop in obj) {
if (deep) {
//深度克隆
newObj[prop] = this.clone(obj[prop], deep);
}
else {
// 浅度克隆
newObj[prop] = obj[prop];
}
}
return newObj;
}
else {
//函数、原始类型
return obj; //递归的终止条件
}
}
<!--插件要考虑通用性,易用性,尽量不要与其他功能冲突,防止污染太多的window上的全局变量,因此我这里使用多个js文件只污染一个全局变量的方式!在helpers.js中添加如下代码
if (!this.myPlugin) {
this.myPlugin = {};
}
-->
<script src="../../plugin/helpers.js"></script> <!--引入插件-->
<script>
var opt = myPlugin.mixin(defaultOptions, option)
console.log(opt);
</script>
结语
整完!!!
js 实现对象的混合与克隆效果,带完整版解析代码[helpers.js]的更多相关文章
- js 实现图片瀑布流效果,可更改配置参数 带完整版解析代码[waterFall.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS实现图片瀑布流效果 页面需求 1 ...
- js 实现淘宝放大镜功能,可更改配置参数 带完整版解析代码[magnifier.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS写淘宝放大镜效果 基本功能: 运 ...
- js 实现淘宝无缝轮播图效果,可更改配置参数 带完整版解析代码[slider.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS写淘宝无缝轮播图效果 需求分析: ...
- js 函数的防抖(debounce)与节流(throttle) 带 插件完整解析版 [helpers.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 函数防抖与节流是做什么的?下面进行通俗的讲解. 本文借鉴:h ...
- js 实现文字滚动功能,可更改配置参数 带完整版解析代码。
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS写文字滚动效果 需求分析: 需要 ...
- js 函数对象的继承 inherit 带 插件完整解析版[helpers.js]
前言: 本人纯小白一个,有很多地方理解的没有各位大牛那么透彻,如有错误,请各位大牛指出斧正!小弟感激不尽. 本篇文章为您分析一下原生JS的对象继承方法 需求分析: 1. ...
- 《JS高程》创建对象的7种方式(完整版)
一.理解对象 ECMA-262定义对象:无序属性的集合,其属性可以包含基本值.对象或者属性. 我们可以把 ECMAScript 的对象想象成 散列表:无非就是一组 名值对,其中值可以是数据或函数. 创 ...
- js串口通信 调用MSCOMM32控件 链接电子秤(完整版实现方案)
硬件环境:RS232转USB串口线*1 电子秤*1(本人采用G&G E600Y-C型号称重仪) 电子秤原装RS232数据线*1 计算机*1 软件环境:RS232转USB串口线驱动(这个可以在串 ...
- Google Analytics统计代码GA.JS中文教程
2010-12-06 11:07:08| 分类: java编程 | 标签:google analytics ga js 代码 |举报|字号 订阅 Google Analytics ...
随机推荐
- 老技术新谈,Java应用监控利器JMX(3)
各位坐稳扶好,我们要开车了.不过在开车之前,我们还是例行回顾一下上期分享的要点. 上期我们深入的聊了聊 JMX,把 JMX 的架构了解了七七八八,最后通过代码实战,解决系列疑问,实现远程动态修改应用参 ...
- Pytest系列(9) - 参数化@pytest.mark.parametrize
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 pytest允许在多个级别启 ...
- Spring Taco Cloud——配料表(Lombok的安装及其注解)
先简单概括下这个项目:外卖订餐平台Web,这个是承接我的这篇博文来续写的https://www.cnblogs.com/yycjavastudy/articles/12666104.html,在这一篇 ...
- 【php】php操作MySQL数据库
一.操作步骤: 1. 连接MySQL数据库并判断是否连接成功2. 选择数据库3. 设置字符集4. 准备SQL语句5. 向MySQL服务发送SQL语句6. 解析处理结果集7. 释放结果集,关闭数据库连接 ...
- 在 Array.filter 中正确使用 Async
本文译自How to use async functions with Array.filter in Javascript - Tamás Sallai. 0. 如何仅保留满足异步条件的元素 在第一 ...
- vue技术栈进阶(02.路由详解—基础)
路由详解(一)--基础: 1)router-link和router-view组件 2)路由配置 3)JS操作路由
- "按钮"组件:<h-button> —— 快应用组件库H-UI
 <import name="h-button" src="../Common/ui/h-ui/basic/c_button"></impo ...
- Git中rebase失败了如何进行恢复
rebase失败后的恢复 记一次翻车现场 记一次翻车的现场,很早之前提的PR后面由于需求的变便去忙别的事情了,等到要做这个需求的我时候,发现已经 落后版本了,并且有很多文件的冲突,然后就用rebase ...
- Linux C++ 网络编程学习系列(5)——多路IO之epoll边沿触发
多路IO之epoll边沿触发+非阻塞 源码地址:https://github.com/whuwzp/linuxc/tree/master/epoll_ET_LT_NOBLOCK_example 源码说 ...
- Centos7_Root密码重置
原因: 最近出去见女朋友,竟然忘了Root用户的密码,此时考验linux基础扎不扎实的时候到了... 操作步骤: 解释补充: mount -o remountr,w / #修改根目录文件系统的权限,实 ...