Javascript进阶知识

原创文章
声明:作者声明此文章为原创,未经作者同意,请勿转载,若转载,务必注明本站出处,本平台保留追究侵权法律责任的权利。
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。

变量、内存、箭头函数

1. let、var、const - 变量提升

var:有变量提升;
let:1. 没有变量提升;2.同一个作用域内不能重复定义同一个名称;3.有着严格的作用域。
const:声明只读的常量。1: 声明的时候就要赋值【const name; // 报错 】;2. 同样没有变量提升,也有严格的作用域;3. 在声明数组或者Object这样的引用对象时,只能保证指针是固定的

xxx.js 复制代码
// 1. 变量提升
console.log(x)
var x = 10;

// 其解析过程为:
var x;
console.log(x); // 所以此处x为undefined
x = 10;


// 如果是let
console.log(y); // 会报错,找不到变量y
let y = 10;

// 2. 作用域
function demo_var() {
    var num = 10;
    if (true) {
        var num = 20;    
    }
    console.log(num); // 为20
}

function demo_let() {
    let num = 10;
    if (true) {
        let num = 20;    
    }
    console.log(num); // 为10
}

// 3. 在循环中的表现
// let 局部作用域
var arr_let = [];
for(let i = 0; i < 5; i++) {
    arr_let[i] = function() {
        console.log(i)    
    }
}
arr_let[2](); // 打印2

// var 变量提升
var arr_var = [];
for(var i = 0; i < 5; i++) {
    arr_var[i] = function() {
        console.log(i)    
    }
}
arr_var[3](); // 打印5

2. 栈内存和堆内存

栈内存:javascript中的5种基本类型:Undefined、Null、Boolean、Number和String,都是直接存储在栈中的。

堆内存:javascript中的其他几种类型:对象Object、数组Array、函数Function等引用类型,都是通过拷贝或者new出来的,这样的数据存储在堆内存中。但引用类型的数据的地址是存储在栈中的。

在访问引用类型数据时,先从栈中获取对象的地址指针,再通过地址指针找到堆内存中的数据。

js 复制代码
var obj = {
    id: 1
};
var obj1 = obj;
obj1.id = 2; // obj中的id变为2

3. 箭头函数

js 复制代码
// 变量声明和使用
function fn1(v) {
    console.log(v);
}
fn1(1234);

// 变量表达式
var fn2 = function(v) {
    console.log(v);
}
fn2(1234);

// 简化成箭头函数
fn = v => console.log(v);

// 写法
var arr = [1,2,3,4,5,6];
const changedArr = arr.map(function(item, index){
    return item + 1;
});
// 改成如下
const changedArr = arr.map((item, index) => {
    return item + 1;
});
// 或者
const changedArr = arr.map(item => item + 1);

// Additions
const fn2 = (x, y, z) => ({id: x, name: y, age: z}); // 当箭头函数返回的是一个对象时,需要加()括起来

注意点:
1.箭头函数不能作为构造函数,不可以使用new;
es5中没有class类的概念,是通过函数实现的,es6才有。
构造函数可以理解为是用来生成模版的函数。
箭头函数中没有this.

js 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
var xiaoming = new Person('xiaoming', 10);

// 箭头函数
var Person = (name) => {
    this.name = name;
}
var xiaogang = new Person('xiaogang'); // Person is not a constructor.

2.箭头函数没有原型对象
构造函数自身的属性和方法是没有办法进行共享的,原型对象的属性和方法是可以被所有实例对象共享的。

原型对象可以理解为是一个父对象,意味着其属性和方法可以被子类继承。

js 复制代码
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.sayHello = function() {
    console.log('sayHello');
}
var xiaoming = new Person('xiaoming', 10);
xiaoming.sayHello();
  1. 箭头函数中不可以使用arguments对象,该对象在函数体内不存在,可以使用rest
js 复制代码
var fun = () => {
    console.log(arguments[1]); // arguments is not defined.
}
fun(1, 2, 3);

arguments是参数集合,但不等同于数组.

js 复制代码
var fun = (...args) => { // 这里的...和【...扩展运算符】是不同的概念,正好相反
    return args.length; // 这里的args就是数组
}
fun(0, 1, 2, 3); // 4
  1. this指向,由于箭头函数不绑定this,所以它会捕获其所在上下文的this的值,作为自己的this值。

暂无评论,快来发表第一条评论吧