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 ...
随机推荐
- O - 推箱子 HDU - 1254(bfs_box + bfs_man)
O - 推箱子 HDU - 1254 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能 ...
- js中的位置属性
原生js中位置信息 clientLeft,clientTop:表示内容区域的左上角相对于整个元素左上角的位置(包括边框),实测,clientLeft=左侧边框的宽度,clientTop=顶部边框的宽度 ...
- 各种版本docker下载的中国开源地址
最近在群里听说Docker很火,于是自己抱着试试的态度,想玩玩,可是遇到了一些问题,记录下来,方便备忘,也方便防止大家被坑. 我的虚拟机装的是centos 6.5,百度了好多教程,丫的,都不解释,就一 ...
- PTA | 1005 继续(3n+1)猜想 (25分)
卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数.例如对 n=3 进行验证的时 ...
- Java线程通讯方法之wait()、nofity() 详解
Java线程通讯方法之wait().nofity() 详解 本文将探讨以下问题: synchronized 代码块使用 notify()与notifyAll()的区别 Java wait(),noti ...
- 跟面试官侃半小时MySQL事务,说完原子性、一致性、持久性的实现
提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关. 而事务的ACID(即原子性Atomicity.一致性Consiste ...
- matplotlib locators
2020-03-23 17:59:59 -- Edit by yangray The Locator class is the base class for all tick locators. Th ...
- 用Jenkins集成ios项目设置多scheme,同一代码自动输出多个环境包 实现便捷切换API环境
Jenkins 安装使用参考我的博客http://www.cnblogs.com/zhujin/p/9064820.html Xcode 配置:说明 一个schema 对应一套环境(如生产,测试),一 ...
- 文件上传——客户端检测绕过(JavaScript检测)(一)
前言 通常再一个web程序中,一般会存在登陆注册功能,登陆后一般会有上传头像等功能,如果上传验证不严格就可能造成攻击者直接上传木马,进而控制整个web业务控制权.下面通过实例,如果程序只进行了客户端J ...
- 当Spring Cloud Alibaba Sentinel碰上Spring Cloud Sleuth会擦出怎样的火花
前言 今年主要会做一个比较完整的微服务项目开源出来.目前已经开始了,刚兴趣的先Star一个吧. 项目:https://github.com/yinjihuan/kitty-cloud 基础框架:htt ...