2.深浅拷贝
2.1 浅拷贝
浅拷贝没有真正的拷贝到值,而是拷贝的是地址,一改全改
2.1.1 数组的浅拷贝
//1.数组的浅拷贝 var arr1 = ["a","b","c",[1,2]]; //a.先声明一个空数组 var arr2 = []; //b.循环数组,将原有数组中的值一个一个复制到目标数组中 for(var key in arr1){ console.log(key + "--------" +arr1[key]); //下标 arr2[key] = arr1[key]; } console.log(arr2); //["a", "b", "c", Array(2)] 里面有引用数据类型,下标为3的这个数组,拷贝的是地址, arr2[3].push(3); //["a", "b", "c", Array(3)] console.log(arr1); //["a", "b", "c", Array(3)] 下标3的这个数组共用的一个地址,一改全改
2.1.2 对象的浅拷贝
//2.对象的浅拷贝 var obj1 = { "name":"梁进", "detail":{ "age":35, "height":175 } } //a.创建一个空对象 var obj2 = {}; //b.循环对象,将原有对象中的值一个一个复制到目标对象中 for(var key in obj1){ obj2[key] = obj1[key]; } console.log(obj2); //{name: "梁进", detail: { "age":35,"height":175}} 里面还有对象,对象只是地址的拷贝 obj2.detail.height = 172; console.log(obj1);//{name: "梁进", detail: { "age":35,"height":175}} 共用一个地址,一改全改
2.2 深拷贝
-
$.extend()实现深拷贝
//2.$.extend(deep,目标对象,被复制的对象) var obj2 = $.extend(true,{},obj1); console.log(obj2); //{name: "梁进", detail: {"age": 35,"height": 175}} obj2.detail.height = 172; console.log(obj2);//{name: "梁进", detail: {"age": 35,"height": 172}} console.log(obj1);//{name: "梁进", detail: {"age": 35,"height": 175}}
-
JSON方法实现深拷贝
//3. 使用JSON方法实现深拷贝 //JSON.stringify(object); //将对象转换成字符串 console.log(JSON.stringify(obj1)); //JSON.parse(str) : 字符串转换为对象 var obj3 = JSON.parse(JSON.stringify(obj1)); console.log(obj3); //{name: "梁进", detail: {"age": 35,"height": 175}} obj3.detail.height = 170; console.log(obj1); //{name: "梁进", detail: {"age": 35,"height": 175}}
-
js原生封装深拷贝的函数
创建一个空对象,循环将原有数据中的内容一个一个复制到空对象中,如果复制的内容中还是对象,使用递归实现深拷贝
//1.判断对象 function getType(data){ return Object.prototype.toString.call(data).slice(8,-1); } //2.深拷贝 function deepCopy(data){ //a.创建一个空对象,空数组 if(getType(data) == "Array"){ var res = []; }else if(getType(data) == "Object"){ var res = {}; }else{ //如果不是引用数据类型,就不存在浅拷贝,直接返回对应的数值 return data; } //b.循环,循环将原有数据中的内容一个一个复制到空对象中 for(var key in data){ //e.如果复制的值还是引用数据类型,这个数据也需要进行深拷贝 if(getType(data[key]) == "Array" || getType(data[key]) == "Object"){ res[key] = deepCopy(data[key]); }else{ res[key] = data[key]; } } //c.返回创建好的对象 return res; } var arr1 = ["a", "b", "c", [1, 2]]; var arr2 = deepCopy(arr1); console.log(arr2); //["a", "b", "c", [1, 2]]; arr2[3].push(3); console.log(arr2); //["a", "b", "c", [1, 2,3]]; console.log(arr1); //["a", "b", "c", [1, 2]]; var obj1 = { "name": "梁进", "detail": { "age": 35, "height": 175 } } var obj2 = deepCopy(obj1) console.log(obj2); //{name: "梁进", detail: {"age": 35,"height": 175}} obj2.detail.height = 172; console.log(obj2); //{name: "梁进", detail: {"age": 35,"height": 172}} console.log(obj1);//{name: "梁进", detail: {"age": 35,"height": 175}}
3.插件
jQuery是封装的JavaScript是一个JavaScript库,将常用 功能封装了起来,但是并不是所有效果都封装了
插件:在现有jQuery的基础上,封装的一些功能效果
3.1 使用第三方插件
-
使用步骤
-
明确插件的功能
-
找插件 jq22 百度 github
-
使用
-
先引入jQuery,再引入插件,再引入插件周边
-
根据源代码,文档说明进行操作
-
-
3.2 自定义插件
jQuery中,方法分两种:
-
第一种对象级别方法: $(selector).方法() $().css() $().val()
-
第二种类级别方法: $.each() $.extend() $.trim()
3.2.1 扩展类级别插件
-
类级别插件:功能性 $.each() $.extend() $.trim()
-
扩展方法:$.extend({ "扩展的方法名":扩展的方法 })
//扩展 $.extend({ //去重 "qc":function(arr){ //1.去重,拿第一个和后面所有的进行比较,如果有一样的,删除后面的哪一个 for(var i = 0;i<arr.length;i++){ for(var j = i + 1;j<arr.length;j++){ if(arr[i] == arr[j]){ arr.splice(j,1); j--; //删除元素,后面会自动补位,下标也需要保持同步 } } } return arr; }, "getMost":function(str){ //1.先假设第一个字符就是出现次数最多的, var maxStr = str[0]; var maxCount = str.split(str[0]).length - 1; //2.验证:循环字符串中每一个字符和出现次数最多字符进行比较,如果有比当前字符出现次数更多,存储那个更多的 for(var i = 0;i<str.length;i++){ if(str.split(str[i]).length-1 > maxCount){ maxCount = str.split(str[i]).length-1; maxStr = str[i]; } } return {"maxStr":maxStr,"count":maxCount} } } //使用 var arr = $.qc([1,1,1,1,1,12,2,2,2,3,4,3,34]); console.log(arr); //[1,12,2,3,4,34]
3.2.2 扩展对象级别插件
-
对象级别方法:$().css() $().click() $().html()
-
扩展对象级别方法:$.fn.extend({扩展的方法名:扩展的方法})
//1.扩展方法 $.fn.extend({ "all": function () { //console.log(this); // $(".box1") 选择器选中的标签 var $that = this; //点击全选按钮,下面的input设置选中 this.find(".all").click(function () { $that.find("ul input").prop("checked", $(this).prop("checked")); }) //点击下面的input,如果全选 this.find("ul input").click(function () { if ($that.find("ul input").length == $that.find("ul input:checked").length) { $that.find(".all").prop("checked", true); } else { $that.find(".all").prop("checked", false); } }) //注意:扩展对象级别方法,需要返回当前对象,方便链式操作 return this; }, "cat": function () { var $that = this; //添加点击事件 $that.find("input").click(function () { var sum = 0; $that.find(":checked").nextAll(".price").each(function (index, elem) { sum += Number($(elem).text().slice(1)); }); $that.find(".sum").text("总价:$"+sum.toFixed(2)); }) return this; //返回当前对象,链式操作 } })
4.zepto.js
zepto.js和jQuery.js类似,zepto.js为了实现轻量级,将不同的功能分成一个一个单独的js文件,需要的时候引入对应的js文件即可。
-
和jQ的区别
<script src="./js/zepto.min.js"></script> <script src="./js/fx.js"></script> <!-- <script src="./js/jquery.js"></script> --> <script> $("div").css("background","teal"); $("div").click(function(){ // $("div").css("background","deeppink"); //需要引入额外的动画模块 $("div").animate({"width":500}) }); console.log($("div").width()); //没有innerWidth,outerWidth 实际大小,如果元素隐藏获取不到元素的宽高位置 console.log($("div").offset()); //{left: 0, top: 0, width: 0, height: 0} 多了width,height </script>
-
touch手势
/* 'swipe':滑动, 'swipeLeft':左滑, 'swipeRight', 'swipeUp':上滑, 'swipeDown', 'doubleTap':双击, 'tap':点击, 'singleTap':单击, 'longTap':长按 */ $("div").on("tap",function(){ console.log("点击"); }) $("div").on("singleTap",function(){ //300ms console.log("单击"); }) $("div").on("doubleTap",function(){ console.log("双击"); })