[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fAZXZdxSt76i9iuTMoe96maufL870Rzi9wqTDcYDzw1U":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":21,"subCategory":24,"comments":26,"status":17,"reason":12,"notice":12,"visitCount":27,"commentCount":28,"keywords":29},25,"2024-01-26T15:29:22.58Z","Javascript进阶知识","# 变量、内存、箭头函数\n## 1. let、var、const - 变量提升\nvar：有变量提升；\nlet：1. 没有变量提升；2.同一个作用域内不能重复定义同一个名称；3.有着严格的作用域。\nconst：声明只读的常量。1: 声明的时候就要赋值【const name; // 报错 】；2. 同样没有变量提升，也有严格的作用域；3. 在声明数组或者Object这样的引用对象时，只能保证指针是固定的\n```xxx.js\n// 1. 变量提升\nconsole.log(x)\nvar x = 10;\n\n// 其解析过程为：\nvar x;\nconsole.log(x); // 所以此处x为undefined\nx = 10;\n\n\n// 如果是let\nconsole.log(y); // 会报错，找不到变量y\nlet y = 10;\n\n// 2. 作用域\nfunction demo_var() {\n    var num = 10;\n    if (true) {\n        var num = 20;    \n    }\n    console.log(num); // 为20\n}\n\nfunction demo_let() {\n    let num = 10;\n    if (true) {\n        let num = 20;    \n    }\n    console.log(num); // 为10\n}\n\n// 3. 在循环中的表现\n// let 局部作用域\nvar arr_let = [];\nfor(let i = 0; i \u003C 5; i++) {\n    arr_let[i] = function() {\n        console.log(i)    \n    }\n}\narr_let[2](); // 打印2\n\n// var 变量提升\nvar arr_var = [];\nfor(var i = 0; i \u003C 5; i++) {\n    arr_var[i] = function() {\n        console.log(i)    \n    }\n}\narr_var[3](); // 打印5\n\n```\n\n## 2. 栈内存和堆内存\n栈内存：javascript中的5种基本类型：Undefined、Null、Boolean、Number和String，都是直接存储在栈中的。\n\n堆内存：javascript中的其他几种类型：对象Object、数组Array、函数Function等引用类型，都是通过拷贝或者new出来的，这样的数据存储在堆内存中。但引用类型的数据的地址是存储在栈中的。\n\n在访问引用类型数据时，先从栈中获取对象的地址指针，再通过地址指针找到堆内存中的数据。\n```js\nvar obj = {\n    id: 1\n};\nvar obj1 = obj;\nobj1.id = 2; // obj中的id变为2\n\n```\n\n## 3. 箭头函数\n```js\n// 变量声明和使用\nfunction fn1(v) {\n    console.log(v);\n}\nfn1(1234);\n\n// 变量表达式\nvar fn2 = function(v) {\n    console.log(v);\n}\nfn2(1234);\n\n// 简化成箭头函数\nfn = v => console.log(v);\n\n// 写法\nvar arr = [1,2,3,4,5,6];\nconst changedArr = arr.map(function(item, index){\n    return item + 1;\n});\n// 改成如下\nconst changedArr = arr.map((item, index) => {\n    return item + 1;\n});\n// 或者\nconst changedArr = arr.map(item => item + 1);\n\n// Additions\nconst fn2 = (x, y, z) => ({id: x, name: y, age: z}); // 当箭头函数返回的是一个对象时，需要加（）括起来\n\n```\n\n注意点：\n1.箭头函数不能作为构造函数，不可以使用new；\nes5中没有class类的概念，是通过函数实现的，es6才有。\n构造函数可以理解为是用来生成模版的函数。\n箭头函数中没有this.\n```js\nfunction Person(name, age) {\n    this.name = name;\n    this.age = age;\n}\nvar xiaoming = new Person('xiaoming', 10);\n\n// 箭头函数\nvar Person = (name) => {\n    this.name = name;\n}\nvar xiaogang = new Person('xiaogang'); // Person is not a constructor.\n\n```\n\n2.箭头函数没有原型对象\n构造函数自身的属性和方法是没有办法进行共享的，原型对象的属性和方法是可以被所有实例对象共享的。\n\n原型对象可以理解为是一个父对象，意味着其属性和方法可以被子类继承。\n```js\nfunction Person(name, age) {\n    this.name = name;\n    this.age = age;\n}\nPerson.prototype.sayHello = function() {\n    console.log('sayHello');\n}\nvar xiaoming = new Person('xiaoming', 10);\nxiaoming.sayHello();\n\n```\n\n3. 箭头函数中不可以使用arguments对象，该对象在函数体内不存在，可以使用rest\n```js\nvar fun = () => {\n    console.log(arguments[1]); // arguments is not defined.\n}\nfun(1, 2, 3);\n```\narguments是参数集合，但不等同于数组.\n\n```js\nvar fun = (...args) => { // 这里的...和【...扩展运算符】是不同的概念，正好相反\n    return args.length; // 这里的args就是数组\n}\nfun(0, 1, 2, 3); // 4\n```\n\n4. this指向，由于箭头函数不绑定this，所以它会捕获其所在上下文的this的值，作为自己的this值。\n\n\n\n\n","Javascript中的变量提升概念以及作用域，如何通过文中案例进行理解，堆内存和栈内存的知识以及变量存储说明，如何理解箭头函数，还有this指向问题。","",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",{"id":21,"name":25,"parentId":21},"JavaScript&HTML&CSS",[],42,0,"javascript,js,js var"]