当前位置:首页 » 《休闲阅读》 » 正文

成为前端牛马第十三天 —— JS基础部分汇总

26 人参与  2024年09月23日 14:40  分类 : 《休闲阅读》  评论

点击全文阅读


一. 数据类型概述

        1. 变量

                变量是储存数据的容器,声明关键字有 let var ,以及常量生成关键字 const

      let age; //声明变量但不赋值,相当于创建一个名为age的容器      let age1 = 18;

         变量提升情况

                使用 var 关键字声明变量时,会产生变量提升,所以我们必须先声明再使用变量,或者使用 let 关键字声明。

/* 2.变量提升情况 var关键字 先声明后使用*/      console.log(num); //undefined      var num = 10;      /* 相当于            var num;            console.log(num);            num = 10       */      // 报错:ReferenceError 引用类型错误

        2. 基本数据类型

                String | Number | Boolean | undefined | null

        3. 引用数据类型

                Array | Object | Function

        4. 数据类型的转换

                4.1 显式转换

                        4.1.1 字符串 布尔类型转数字类型

                                方法有 Number() | parseInt() | parseFloat()

/* 一.转数字类型 Number语法 */      /* 1.字符串转数字 */         var a = "123";         var b = Number(a);         console.log(typeof a, typeof b);      //   string number      /* 2.null转数字 会转换成0*/         var a = null;         var b = Number(a);         console.log(typeof a, typeof b, b);      //object number 0      /* 3.undefined转数字 会转换成NaN,非数字,本质还是数字类型*/         var a = undefined;         var b = Number(a);         console.log(typeof a, typeof b, b);      //   undefined number NaN      /* 4.boolean转数字 true对应1 false对应0 */      /* 5.小数转换 */         var a = 123.45;         var b = Number(a);         console.log(typeof a, typeof b, b);      //   number number 123.45      /* 6.带字母字符串转换 */         var a = "123abc123";         var b = Number(a);         console.log(typeof a, typeof b, b);      //   string number NaN      /* 二.parseInt 转换方法,主要转换整数,类似于一个数字一个数字转换,遇到字母或是小数点就停止 */         var a = 123.45;         var b = parseInt(a);         console.log(typeof a, typeof b, b);      //   number number 123 会省略后面的小数         var a = "123abc123";         var b = parseInt(a);         console.log(typeof a, typeof b, b);      //   string number 123      /* 三.parseFloat 转换方法,与parseInt类似,可以保留小数 */
                        4.1.2 布尔类型 数字类型转字符串

                                方法有 String() | toString()

/* 一. 转换为字符串类型 String()写法 任何类型皆可转换 */         let a = null;         let b = String(a);         console.log(typeof a, typeof b, b);      //   object string null      /* 二. toString() 写法 具有限制,值为null和undefined时会报错可以看做是方法的调用,null和undefined是不能调用方法的*/      let a = true;      let b = a.toString();      console.log(typeof a, typeof b, b);      let num = 14;      console.log(num.toString(16)); //进制转换      //boolean string true
                        4.1.3 字符串 数字类型转布尔类型
/* 一. 类型转换为布尔值 */      /* 只有0,'',undefined,null,NaN 这些值会转换成false,其余都是true */         let a = "";         let b = Boolean(a);         console.log(typeof a, typeof b, b);      //   string boolean false

                4.2 隐式转换

                        浏览器通过符号或数字进行数据类型的自动转换

// 二、隐式转换 (浏览器自动转换)      // 1) 转字符串类型      // 任意数据类型和字符串拼接,都会变成字符串类型      // +  这个加号运算符(加法运算、字符串拼接)       console.log(10 + 20);// 30       console.log(10 + "abc");// '10abc'       console.log(typeof 10 );// 'number'       console.log(typeof 10  + "abc");// 'numberabc'       console.log(typeof (10  + "abc"));// 'string'       console.log(typeof true);//'boolean'       console.log(typeof (true + ""));//'string'       console.log(typeof (undefined + ""));//'string'      // 2) 转数字类型      // 主要数字字符串使用这个“-”可以隐式转换成数字类型      // 任何数字减去0都等于其本身      // 任何数字乘以1都等于其本身      // -   这个符号号运算符(减法运算、转数字)       console.log(100 - 60);// 40       console.log(typeof "100");// 'string'       console.log(typeof ("100" - 0));// 'number'       console.log(typeof ("100" * 1));// 'number'      // 3)两个等于号表示比较值的大小,不比较数据类型      // ==      // 0 == false      // "" == false      // 1 == true      console.log(0 == false); // true      console.log("" == false); // true      console.log(0 == ""); // true      console.log(1 == true); // true      console.log(undefined == false); // false      // 举例:1 > 2 < 3 这个表达式执行的结果: true      // 1 > 2  表示 false  隐式转换为0      // 0 < 3  结果 true

        5. 运算符

                5.1 数学运算符

      // + - * / %      /* 倒计时转换效果 */      let time = 1000;      let hour = parseInt(time / 60);      let min = time % 60;      console.log(hour + ":" + min);      /* 字符串数学运算 */      console.log(1 + "2" * 3 + 4);      //非加号的字符串数学运算都带有隐式转换,会转换成数字类型进行运算      /* 自增自减运算 ++ --*/      let num = 10;      console.log(num++); //10 先输出再运算      console.log(num); //11      console.log(++num); //11 先运算再输出

                5.2 赋值或逻辑运算符

/* JS的赋值运算符有 = += -= *= /=*/      /* 比较运算符有 == === != !== */      console.log(true == 1); //true      console.log("" == 0); //true      console.log(undefined == 0); //false      /* 逻辑运算符 || && ! */      /* 逻辑或 || 一真全真,全假为假 */      /* 逻辑与 && 全真为真,一假为假 */      /* || 的运用  默认值操作*/      let data = "" || "侬好";      console.log(data); //'侬好'      /* && 的运用 */      let data1 = true && 100; //&& 运算符所有的条件都会执行,有值赋值      console.log(data1);

二. 字符串

        1.概念

        字符串是一个 JS 内的基本数据类型,在 JS 内用单引号 ' ' 或者双引号 " " 包裹的内容就叫做 字符串。

        2.创建字符串

// 1. 字面量方式创建 字符串var str1 = 'hello world'var str2 = "hello world"console.log(str1)// hello worldconsole.log(str2)// hello world

         使用构造函数创建字符串,是以 new 创建对象的形式,所以字符串会被存放在堆内存,变量str1和str2存放的是地址值,str1==str2 是false,str1===str2 也是false

// 2. 构造函数创建字符串var str1 = new String('hello world')var str2 = new String("hello world")console.log(str1)// String {"hello world"}console.log(str2)// String {"hello world"}

        3.字符串相关方法

/* 字符串常用方法 */      //1.字符串长度      const str = "hello";      console.log(str.length); //5      //2.字符串拼接      const str1 = "hello";      const str2 = "world";      console.log(str1 + str2); //helloworld      //3.字符串截取      const str3 = "hello world";      console.log(str3.slice(0, 5)); //hello      //4.字符串查找 indexOf charAt      const str4 = "hello world";      console.log(str4.indexOf("h")); //0      console.log(str4.indexOf("o", 5)); //从第五个字符开始查找o      //4.1 charAt      const str41 = "hello";      console.log(str.charAt(1)); // 输出结果:e      console.log(str[1]); // 输出结果:e      console.log(str.charAt(5)); // 输出结果:''      console.log(str[5]); // 输出结果:undefined      //4.2 includs      let str42 = "Hello world!";      str.includes("o"); // 输出结果:true      str.includes("e", 2); // 输出结果:false,ongoing第二个字符开始查找e      //4.3 match 返回包含值与索引的数组,通过点语法输出      let str43 = "abcdef";      console.log(str43.match("c").input); // ["c", index: 2, input: "abcdef", groups: undefined]      //5.字符串替换      const str5 = "hello world";      console.log(str5.replace("world", "javascript")); //hello javascript      //6.字符串分割,生成数组 split substr      const str6 = "hello world";      console.log(str6.split(" ")); //(2) ["hello", "world"]      //正则匹配分割      const list = "apples,bananas;cherries";      const fruits = list.split(/[,;]/);      console.log(fruits); // 输出结果:["apples", "bananas", "cherries"]      //6.1 substr []      let str61 = "abcdefg";      str.substr(1, 6); // 输出结果:"bcdefg"      str.substr(1); // 输出结果:"bcdefg" 相当于截取[1,str.length-1]      str.substr(); // 输出结果:"abcdefg" 相当于截取[0,str.length-1]      str.substr(-1); // 输出结果:"g"      //6.2 substring [)      let str62 = "abcdefg";      str.substring(1, 6); // 输出结果:"bcdef" [1,6)      str.substring(1); // 输出结果:"bcdefg" [1,str.length-1]      str.substring(); // 输出结果:"abcdefg" [0,str.length-1]      str.substring(6, 1); // 输出结果 "bcdef" [1,6)      str.substring(-1); // 输出结果:"abcdefg"      //7.字符串拼接      let str7 = "abc";      console.log(str7.concat("efg")); //输出结果:"abcefg"      console.log(str7.concat("efg", "hijk")); //输出结果:"abcefghijk"      console.log(str7.concat("efg", ...str));      console.log(str + str7);      //8.移除左右空格,在input输入框中有运用      let str8 = "  abcdef  ";      str8.trim(); // 输出结果:"abcdef"      //9.字符串的转换 数组转字符串join() 字符串转数组split(',')      let str91 = "abcdef",        str92 = 123123123;      arr = [1, 2, 3];      console.log(str92.toString()); // "123123123"      console.log(typeof str2.toString()); //string      console.log(arr.toString()); //1,2,3      console.log(arr.toString().split(",")); //split分割逗号,['1','2','3']      /* //7.字符串转大写      const str7 = "hello world";      console.log(str7.toUpperCase()); //HELLO WORLD      //8.字符串转小写      const str8 = "HELLO WORLD";      console.log(str8.toLowerCase()); //hello world */      /* 补充 */      //1.判断字符串以什么字符开头及结尾      let s1 = "Hello world!";      s1.startsWith("Hello"); // 输出结果:true      s1.startsWith("Helle"); // 输出结果:false      s1.startsWith("wo", 6); // 输出结果:true      s1.endsWith("!"); // 输出结果:true      s1.endsWith("llo"); // 输出结果:false      s1.endsWith("llo", 5); // 输出结果:true

三. 数组

        1.概念

                一组有序的数据集合,可以同时存储不同类型的值,并且长度是动态的,可以根据需要随时添加或删除元素。

        2.声明

// 1.字面量创建let arr1 = [1, 2, 3];// 2.构造函数创建let arr2 = new Array(10, 20, 30);let arr3 = new Array(7);//创建一个长度为7的空数组

        3.访问元素

                数组含有规律的索引,通过从0开始到长度-1的索引值来访问和修改元素

let arr = [1,2,3]console.log(arr[0]);//1arr[1]=5console.log(arr);//[1,5,3]

        4.数组遍历

                利用数组有规律的索引,通过for循环的方式进行数组遍历,能够按需取出数组元素

let arr = [1,2,3];for(let i = 0 ; i < arr.length ; i++){    console.log(arr[i])//1,2,3}

        5.相关方法

/* 数组常用方法 */      //1.数组添加      var arr = [1, 2, 3, 4, 5];      res = arr.push(6);      console.log(res); //返回添加的数值6      console.log(arr);      //1.2 unshift(数据)方法向数组的开头添加一个或更多元素,并返回新的数组长度。      var arr = [1, 2, 3, 4, 5];      res = arr.unshift(0);      console.log(res); //[6]      console.log(arr); //[0,1,2,3,4,5]      //2.数组删除 pop() 删除数组最后一个元素      var arr = [1, 2, 3, 4, 5];      res = arr.push();      console.log(res); //[5]      console.log(arr); //[1,2,3,4]      //2.1shift()方法,删除数组的第一项,并返回删除的项,原数组改变      var arr = [1, 2, 3, 4, 5];      res = arr.shift();      console.log(res); //[1]      console.log(arr); //[2,3,4,5]      //3.数组翻转 reverse()方法用于颠倒数组中元素的顺序。返回值:返回颠倒后的数组,原数组改变      var arr = [1, 2, 3, 4, 5];      res = arr.reverse();      console.log(res); //[5,4,3,2,1]      console.log(arr); //[5,4,3,2,1]      //3.1.数组翻转 for循环      let arr1 = [];      for (let i = arr.length - 1; i >= 0; i--) {        arr1.push(arr[i]);      }      console.log(arr1);      //4.数组排序 sort()方法用于对数组的元素进行排序。返回值:返回排序后的数组,原数组改变      var arr = [1, 3, 2, 5, 4];      res = arr.sort();      console.log(res); //[1,2,3,4,5]      console.log(arr); //[1,2,3,4,5]      //4.1.数组排序 for循环      for (let i = 0; i < arr.length; i++) {        for (let n = i + 1; n < arr.length; n++) {          if (arr[n] > arr[i]) {            let temp = arr[i];            arr[i] = arr[n];            arr[n] = temp;          }        }      }      console.log(arr); //[5,4,3,2,1]      //5.数组截取 slice(start,end)方法可从已有的数组中返回选定的元素。返回值:返回截取后的数组,原数组不改变      var arr = [1, 2, 3, 4, 5];      res = arr.slice(1, 3);      console.log(res); //[2,3]      console.log(arr); //[1,2,3,4,5]      //5.1.数组截取 splice(开始的索引,结束的索引,添加的元素) 截取从开始到结束的元素,并添加元素,返回被删除的元素      var arr = [10, 60, 8, 56, 48, 75];      res = arr.splice(1, 2, 100, 200);      console.log(arr); //[10, 100, 200, 56, 48, 75]      console.log(res); //[60, 8]      //6.数组合并concat() 合并数组,返回新数组      var arr = [10, 60, 80, 50, 40, 70, 10, 40];      res = arr.concat(10, "测试", 40);      console.log(arr); //[10, 60, 80, 50, 40, 70, 10, 40]      console.log(res); //[10, 60, 80, 50, 40, 70, 10, 40, 10, '测试', 40]      console.log([...arr, "测试"]); //拓展运算符      //7.数组转字符串 join()把数组中的元素用指定的字符串连接起来  map(item=>{}).join() js转html结构      var arr = [10, 60, 80, 50, 40, 70, 10, 40];      res = arr.join("+");      console.log(arr); //[10, 60, 80, 50, 40, 70, 10, 40]      console.log(res); //10+60+80+50+40+70+10+40      //8.数组查找 indexOf(元素,起始索引位置)      var arr = [10, 60, 80, 50, 40, 70, 10, 40];      res = arr.indexOf(40, 3);      console.log(arr);      console.log(res);      /* 9.ES6新增 */      //forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。      //item: 数组中正在处理的当前元素。      //index: 可选,数组中正在处理的当前元素的索引。      //arr: 可选,forEach() 方法正在操作的数组。      var arr = [1, 2, 3, 4, 5];      console.log(arr);      var res = arr.forEach(function (item, index, arr) {        console.log(item, index, arr);      });      //map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。      var arr = [1, 2, 3, 4, 5];      console.log(arr); //[1, 2, 3, 4, 5]      var res = arr.map(function (item) {        return item * 200;      });      console.log(res); //[200, 400, 600, 800, 1000]      //filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。      //注意: filter() 不会对空数组进行检测。      //注意: filter() 不会改变原始数组。      var arr = [1, 20, 35, 44, 50];      console.log(arr); //[1, 20, 35, 44, 50]      var res = arr.filter(function (item) {        return item > 40;      });      console.log(res); //[44, 50]      //every 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。      //如果所有元素都通过检测,则返回 true;否则返回 false。      var arr = [1, 20, 35, 44, 50];      console.log(arr); //[1, 20, 35, 44, 50]      var res = arr.every(function (item) {        return item > 20;      });      console.log(res); //false      //some =>      //some 方法是用来检测数组中是否含有符合条件的元素      //如果有,则返回true,否则返回false      //some 方法不会对空数组进行检测      //some 方法不会改变原始数组      var arr = [1, 20, 35, 44, 50];      console.log(arr); //[1, 20, 35, 44, 50]      var res = arr.some(function (item) {        return item > 22;      });      console.log(res); //true      //find()方法      //find()方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。      //find()方法不会改变原始数组。      var arr = [1, 20, 35, 44, 50];      console.log(arr); //[1, 20, 35, 44, 50]      var res = arr.find(function (item) {        return item > 22;      });      console.log(res); //35      //reduce =>      //用于把数组中的所有值相加得到一个值      //result => 初始值      //item => 数组中的每一个值      //result => 每一次相加的结果      var arr = [1, 20, 35, 44, 50];      console.log(arr); //[1, 20, 35, 44, 50]      var res = arr.reduce(function (result, item) {        return result + item;      });      console.log(res); //150

        5.二维数组 

                一个数组内的元素还是数组形式,形如以下的数组,称为二维数组

let arr = [        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],      ];

                 二维数组的遍历 : 采用双重循环的方式

for (let i = 0; i < arrData.length; i++) {        for (let j = 0; j < arrData[i].length; j++) {          return arr[i][j]        }      }

                二维数组的动态生成

/* 渲染一个二维数组 */function getArray(col,row) {    let arr = new Array(col);    for (let i = 0; i < col; i++) {        arr[i] = new Array(row);        for (let j = 0; j < row; j++) {            a[i][j]=1        }    }    return arr;};

四. 对象

        1.概念

                对象:以键值对形式出现的数据集合 {key:value}

        2.声明方式

// 1.字面量创建let ming= {name:"阿明",age:22,};// 2.构造函数创建let ming= new Object();ming.name = "阿明";ming.age = 22;

        3.访问和添加删除对象属性

                3.1访问对象属性

                        方法一 : 通过.语法访问

let ming= {name:"阿明",age:22,};console.log(ming.name);//阿明

                        方法二 : 通过键名方式  object[key] 

let ming= {name:"阿明",age:22,};console.log(ming[age]);//22

                3.2添加删除对象属性

                        通过.语法添加

let ming= {name:"阿明",age:22,};ming.study='H5';console.log(ming)//{name:'阿明',age:22,study:'H5'}

                        通过delect删除

let ming= {name:"阿明",age:22,};delete ming.age;// 或者 delete ming[age]console.log(ming)//{name:'阿明'}

        4.遍历对象

                对象是不能像数组一样使用普通for循环遍历,因为对象的键名多是没有规律的,但是可以通过 for in 这类方法遍历

let ming= {name:"阿明",age:22,};for(let key in ming){let value = ming[key];    console.log(key + ' ' + value);    //name '阿明'    //age 22}

        5.相关方法

//1.Object.entries(obj):返回对象内可枚举键值对组成的数组;      const obj1 = { a: "1", b: 2 };      console.log(Object.entries(obj1)); // [ ['a', '1'], ['b', 2] ]      //2.Object.keys(obj):返回对象内可枚举键组成的数组;      // 简单数组,数组的keys值为index索引      var arr = ["a", "b", "c"];      console.log(Object.keys(arr)); // console: ['0', '1', '2']      // 简单对象      const obj2 = { a: 1, b: 2 };      console.log(Object.keys(obj2)); // [a,b]      //3.Object.values(obj):返回对象内可枚举值组成的数组;      // 简单数组,数组的keys值为index索引      var arr = ["a", "b", "c"];      console.log(Object.values(arr)); // console: ['a', 'b', 'c']      // 简单对象      const obj3 = { a: 1, b: 2 };      console.log(Object.values(obj3)); // [1,2]      //5、delete 操作符:用于删除对象的某个属性      let obj5 = { a: 1, b: 2 };      // delete obj;// 不能直接删除对象,这里会报错      delete obj5.a;      console.log(obj5); // 输出{b: 2};      //6、hasOwnProperty():返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键);      let obj6 = { a: 1, b: 2 };      console.log(obj6.hasOwnProperty("a")); // true      console.log(obj6.hasOwnProperty("c")); // false      //7、in 操作符:返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键);      let obj7 = { a: 1, b: 2 };      console.log("a" in obj7); // true      console.log("c" in obj7); // false      //8、Object.assign():用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。      let obj8 = { a: 1, b: 2 };      let obj9 = { c: 3, d: 4 };      let obj10 = Object.assign(obj8, obj9);      let obj11 = { ...obj8, ...obj9 };      console.log(obj10); // {a: 1, b: 2, c: 3, d: 4}      console.log(obj11);      //9、Object.defineProperty() :会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。      /*obj: 要定义属性的对象。prop: 要定义或修改的属性的名称或 Symbol 。descriptor: 要定义或修改的属性描述符。*/      //Object.defineProperty(obj, prop, descriptor);      //使用      const obj = {};      Object.defineProperty(obj, "property", {        value: 1, // value值      });      //== 等价于 ==      Object.defineProperty(obj, "property", {        value: 1, // value值        configurable: false, // 是否可删除        enumerable: false, // 是否可遍历        writable: false, // 是否可修改      });      //所以obj不可修改删除遍历操作,除非把上面的三个属性设置为true      console.log(obj); // { property: 1}      delete obj.property; // 删除操作,不生效      console.log(obj); // { property: 1}      obj.property1 = 23; // 修改操作,不生效      console.log(obj); // { property: 1}      for (let i in obj) {        // 遍历操作,不生效        console.log(i); // 无打印      }

五. 函数

        1. 函数概念

                JS 是一门函数式的编程语言,函数是可以重复利用的代码块

        2. 函数声明

                函数名()

               function 函数名(形式参数...){}

                定义变量接收函数 不能在声明之前调用

                const 函数名 = function(){}

         3. 构造函数

                3.1概念

                        构造函数是一种用于构建对象的代码块。用于构建、设计对象的函数,需要使用new来调用,普通函数作用域的this,往往指向window,因为其在全局环境下。构造函数作用域的this,指向构造函数所创建的实例,因为它是由new来调用。this 是指针变量。不同的作用域this指向是不同。

                3.2 内置构造函数

                        String 、Number 、 Boolean 、 Array 、Object 、Date 、Function ...

                        构造函数的命名规范 名称首字母大写。

                3.3 基本使用

                        采用new操作符调用的函数都是构造函数, const sayHi = new Function('')

function Student(name, age) {        this.name = name;        this.age = age;        this.sayHi = function () {          console.log("侬好");        };      }      const student = new Student("咸鱼茄子煲", 19);      student.sayHi();      console.log(student.age);      console.log(student.name);      console.log(student);

六. JS语句

/* javascript 语句 */      //1.判断语句      if else | if (else if) else | switch      //2.循环语句      for循环 while循环 do while循环      /* 2.1 for循环 */      for (初始化; 终止条件; 增量) {        // 循环体代码      }      for (let i = 0; i < 5; i++) {        console.log(i);      }      /* 2.2 while循环 */      while (条件) {        // 循环体代码      }      let i = 0;      while (i < 5) {        console.log(i);        i++;      }      /* 2.3 do while 循环 */      do {        // 循环体代码      } while (条件);      let j = 0;      do {        console.log(j);        j++;      } while (j < 5);

七. 原型链

        1.构造函数的原型对象

                在js中,一个特殊的每一个对象(函数也是对象)都有属性叫做原型(prorotype),它指向另一个对象,这个对象(Object.prototype)被称为原型对象, 原型对象是用来共享属性和方法的。

// 原型 prototype :每个构造函数都有的属性,类型是object,也称原型对象,通过原型对象添加自定义方法      // 构造函数.prototype      console.log(Array.prototype); //挂载很多方法 push pop      // arr调用join方法,但arr实例对象没有这个方法,会找到Array构造函数,再找到其原型对象身上的join方法      let arr = [1, 2, 3];      let arrStr = arr.join("");      console.log(arrStr);      /* 来个栗子 */      function App() {}      App.prototype.sayHi = function (params) {        console.log(this); //指向实例对象,谁调用指向谁        console.log("你好啊" + params);      };      let app = new App();      app.sayHi("阿明");      console.log(app.__proto__);

        2.实例对象的隐式原型 

                在js中,每个实例对象都有一个“ __proto__ ”属性,这个__proto__就被称为隐式原型,它与构造函数的原型对象有相互指向的关系,也就是 obj__proto__ === Object.prototype。

八. 深浅拷贝

        1.概念

                拷贝就是复制或是克隆。js的数据类型主要有基本数据类型和引用数据类型,其中基本数据类型存于栈内存,存储在变量的就是实际的元素;而引用数据类型存于堆内存,存储在变量的为指向堆内存的地址值,所以这两种数据类型在拷贝使用中会有不同。

/* 基本数据类型与引用数据类型的存储 */      //1.基本数据类型:存在栈内存,变量存储元素值      let width = "100px";      //2.引用数据类型:存在堆内存,变量存储地址值      let _obj = {        height: "100px",      };      /* 数据拷贝和地址拷贝 */      let a = [1, 2, 3];      let b;      b = a;      b[0] = 100;      console.log(a); //[100,2,3]      console.log(b); //[100,2,3]      let c = [1, 2, 3];      let d = [];      d[0] = c[0];      d[0] = 100;      console.log(c); //[1,2,3]      console.log(d); //[100]

        数据拷贝主要是元素赋值操作,两个变量互不影响;但地址拷贝不同,赋值变量的是地址值,也就让两个变量都指向同一个地址的引用数据类型,当一个变量改动数据时,另一个变量也回随之改变。

        2.浅拷贝 

                适用于元素为简单数据类型的情况

// 数组内为基本数据类型      let arr1 = [1, 2, 3];      // 数组包含引用数据类型      let arr2 = [1, 2, { x: "50px" }];      //封装浅拷贝函数      function simpleCopy(data) {        //根据data判断要设置的数据类型        let newData = Array.isArray(data) === true ? [] : {};        for (const key in data) {          newData[key] = data[key];        }        return newData;      }      //数组包含基本数据类型      let newArr1 = simpleCopy(arr1);      newArr1[0] = 100;      console.log(arr1);      console.log(newArr1); //不会影响原数组元素      //数组包含引用数据类型      //浅拷贝的是地址值,也就是arr1[2]和newArr2[2]共同指向同一个对象      let newArr2 = simpleCopy(arr2);      newArr2[2].x = "100px";      console.log(arr2);      console.log(newArr2); //会将原数组的数据改变

        3.深拷贝

                适用于元素带有引用数据类型的情况

let obj = {        a: 1,        b: 2,        obj: {          x: 100,          y: 200,        },      };      let arr = [1, 2, { o: 100, p: 100 }];      //封装深拷贝函数      function deepClone(data) {        if (data && typeof data === "object") {          //1.根据传入的数据结构创建对应的数据结构          let newObj = Array.isArray(data) ? [] : {};          //2.进行循环,如果是普通类型,调用浅拷贝          for (const key in data) {            if (data.hasOwnProperty(key)) {              //3.判断如果是引用数据类型              if (data[key] && typeof data[key] === "object") {                //4.将内部的引用数据类型进行递归,也就是剥层,直到简单数据类型的浅拷贝                newObj[key] = deepClone(data[key]);              } else {                newObj[key] = data[key];              }            }          }          return newObj;        } else {          return data;        }      }      let newObj = deepClone(obj);      newObj.a = 100;      newObj.obj.x = 1;      console.log(obj);      console.log(newObj);      let newArr = deepClone(arr);      newArr[0] = 100;      newArr[2].o = 1;      console.log(arr);      console.log(newArr);

 

前者数据的改变不会影响后者


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/163473.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1