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如何运行
JVM内存结构 可以看出JVM从宏观上可以分为 ‘内部’ 及 ‘外部’ 两个部分(便于记忆理解): ‘内部’包含:线程共享(公有)数据区 和 线程隔离(私有)数据区 ‘外部’包含:类加载子系统.垃 ...
- xmind转为markdown
先将xmind导出为.opml 将opml导入Typora (需要安装pandoc)
- Appium自动化(1) - 环境准备详细教程
Appium需要用到的工具 链接:https://pan.baidu.com/s/1od9x-1l0ALGRT5T6QFDHWg 提取码:bnhq 安装Appium Pyhton client包 1. ...
- 1089 Insert or Merge (25分)
According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, and gr ...
- 关于AUI框架自学心得
2018年8月25日今天星期六,这段时间接触到移动端布局框架AUI,借着早上一个小时时间大致看了一下开发文档(后面统称文档),对AUI一点认识. 目前2.0版本为最新版,这个版本和1.0比较升级很多. ...
- hive常用函数五
复合类型构建操作 1. Map类型构建: map 语法: map (key1, value1, key2, value2, …) 说明:根据输入的key和value对构建map类型 举例: hive& ...
- hive常用函数三
日期函数 1. UNIX时间戳转日期函数: from_unixtime 语法: from_unixtime(bigint unixtime[, string format]) 返回值: string ...
- go中的error小结
go中的error error和panic error接口 go中err的困局 推荐方法 总结 参考 go中的error go中的错误处理,是通过返回值的形式来出来,要么你忽略,要么你处理(处理也可以 ...
- redis中的分布式锁
分布式锁的实现场景 在平时的开发中,对于高并发的开发场景,我们不可避免要加锁进行处理,当然redis中也是不可避免的,下面是我总结出来的几种锁的场景 Redis分布式锁方案一 使用Redis实现分布式 ...
- spring 中 hibernate 的 2种 配置方式(新旧 2种方式)
Spring对hibernate配置文件hibernate.cfg.xml的集成,来取代hibernate.cfg.xml的配置 Spring对hibernate配置文件hibernate.cfg.x ...