JS知识点补充

Posted 煜成'Studio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS知识点补充相关的知识,希望对你有一定的参考价值。

JS知识点补充

1如果你要改一个数组的其中一个值是能改的,但是字符串是不能单独修改其中的值的

//数组
let arr = [1, 2, 3];
arr[1] = 1;
console.log(arr); //[ 1, 1, 3 ]
//字符串不能修改
let arr = 'hello';
arr[1] = 1;
console.log(arr); //hello

2在函数形参中对对象解构赋值同时也需要添加默认值的时候,注意以下

//对象的结构赋值
let obj = name: 'nodejs', age: 11;
function func(name, age) 
    console.log(name, age);

func(obj); //nodejs 11

//没有传入实参会报错
function func(name, age) 
    console.log(name, age);

func(); //报错

//没有传入实参,但是相当于添加了默认值undefined
function func(name, age = ) 
    console.log(name, age);

func(); //undefined undefined

//**********
//没有传入实参,但是分别添加了默认值,注意name = "nodejs", age = 11是添加默认值而不是一个对象
//形参中必须这样写name = "nodejs", age = 11 = ,相当于之前先添加默认值undefined,然后又分别把默认值改为了'nodejs'和11
//只这样写name = "nodejs", age = 11会报错,因为这样写既不是对象的格式,也不是对象添加默认值的样式
function func(name = "nodejs", age = 11 = ) 
    console.log(name, age);

func(); //nodejs 11

3箭头函数中,函数体只有一个语句可以省略大括号,这种化简的写法是会返回一个值,给到函数的调用结果

let func = x1 => console.log(x1);
let ret = func(10); //获取这个函数的返回值,因为console.log的执行结果就是undefined,
//运行完之后相当于return undefined
console.log(let); //undefined

let func2 = () => 999 + 1;
let ret2 = func2();
console.log(ret2); //1000,这个有返回值
//let func2 = () => 999 + 1;这条语句相当于let func2 = () => return 999 + 1;

如果函数体里只有一个语句且其返回值是一个对象,不能用简写的方式,因为大括号是函数体的还是对象的意义不明,会报错

4this的指向问题

function People(name, age) 
	this.name = name;
	this.age = age;
	this.say = function() 
		console.log(this.name); //this指向调用者
	

let p1 = new People("zhangsan", 18);
p1.say(); //zhangsan

function People(name, age) 
	this.name = name;
	this.age = age;
	this.say = function() 
		setTimeout(function() 
			console.log(this.name); //定时器里的function是一个新开辟的局部作用域,有自己的作用域,所以this指向丢失
		, 1000)
		
	

let p2 = new People("zhangsan", 18);
p2.say(); //undefined

//之前用这种方式
function People(name, age) 
	this.name = name;
	this.age = age;
	this.say = function() 
		let _this = this;
		setTimeout(function() 
			console.log(_this.name); 
		, 1000)
		
	

let p2 = new People("zhangsan", 18);
p2.say(); //zhangsan

//也可以使用箭头函数,箭头函数没有自己的作用域,它的作用域和外层是相同的
function People(name, age) 
	this.name = name;
	this.age = age;
	this.say = function() 
		setTimeout(() => 
			console.log(this.name); 
		, 1000)
		
	

let p2 = new People("zhangsan", 18);
p2.say(); //zhangsan

//在DOM操作中也可能遇到这种情况
let oDom = document.getElementById("odiv");
oDom.onclick = function() 
	setTimeout(function() 
		this.style.width = "500px"; //会出现问题
	, 1000)


//可以使用箭头函数进行修改
let oDom = document.getElementById("odiv");
oDom.onclick = function() 
	setTimeout(() => 
		this.style.width = "500px";
	, 1000)


//如果是以字面量形式创建的对象,不适合书写箭头函数
let obj = 
	name: "nodejs",
	age: 11,
	say: () => 
		console.log(this.name);
	

obj.say(); //undefined,因为箭头函数this指向外层,这里指向的是Windows,而不是指向obj
//所以要用之前常用的写法
let obj = 
	name: "nodejs",
	age: 11,
	say: function() 
		console.log(this.name);
	

obj.say(); //nodejs

5ES6中创建类中constructor是什么时候执行的?

创建对象的时候执行的/实例化的时候

class Animal 
	constructor(name) 
		this.name = name;
	
	showName() 
		...
	

let dog = new Animal("小白");

6ES5中的静态方法,ES6的形式也需要掌握

//定义类
function Animal(name) 
	this.name = name;

//给类的实例定义方法,通过实例调用
Animal.prototype.showName = function () 
	console.log(this.name);

//给类定义静态方法,必须通过类来调用
Animal.eat = function () 
	console.log("进食");

//根据函数实例化对象
var a = new Animal("Tom");
//调用对象的方法
a.showName();
//调用类的静态方法
Animal.eat();

实例属性和实例方法都是给实例对象去调用的;

每一个实例对象在内存中是独立的,各自用自己的属性和方法;

let dog = new Animal(“小白”);左右哪些事情?1创建了新的对象2调用了constructor方法并传入对应的参数3把这个对象的指向给到dog标识符这个内存空间;

因为上条第3点中传入参数并执行了constructor方法,所以新对象才有了这些属性。

静态方法是通过类名来调用的

在类中,某个方法如果不用到this,我们可以理解为这个方法就不是给实例用的,可以设置为静态方法

//静态属性
//在ES6中静态方法是在class中用static来定义的,但是不能用static来定义静态属性,typeScript可以这样定义,而ES6中要是想定义静态属性,可以在class Animal类外面用Animal.num = 10;这样来定义
//ES6中静态方法也可以通过类的extends继承拿到

7在类的继承中如果子类有和父类相同的方法名,子类实例调用该方法时调用的是子类的方法(这就叫做重写),同理当子类中没有constructor时,子类可以调用父类的属性,但是子类中有constructor的时候,相当于重写了,此刻子类实例只能调用子类的constructor里的属性,如果想要调用父类的属性,需要用super()调用回父类的constructor,父类中constructor()需要的形参在super()中传入,在创建子类对象的时候需要传入实参,所以子类的constructor中需要相应的形参,通过子类的constructor形参传递到super中的参数,再调用回父类的constructor中;子类中的this是在调用super方法之后才起作用,所以super要放在constructor内的第一行位置

8一个js文件就是一个模块,提高代码的可维护性,其次可以复用,编写代码不必从零开始,还可以避免函数名和变量名冲突,模块化主要是方便项目的开发和维护

模块的作用域是私有的,内部定义的变量或者函数,只有当前的文件/模块可以使用,其他模块需要使用的话,以CommonJS的Modules规范:Nodejs为例,需要导出exports或者module.exports,导出的时候,以对象的方式进行导出,在要用的模块内,需要先引入导出的那个模块,使用require引入,引入后需要用一个变量来接收导入的对象。

模块化定义规范:

AMD规范: Require.js

CMD规范: Sea.js

//AMD和CMD是Nodejs出来之前使用的老的规范

CommonJS的Modules规范: Nodejs

ES6模块化规范

以上是关于JS知识点补充的主要内容,如果未能解决你的问题,请参考以下文章

VSCode 配置 用户自定义代码片段 自定义自动代码补充

如何手动补充陈年老库(或纯 JS 代码)的 TypeScript 类型?

JS知识点补充

JS知识点补充

JS知识点补充

JS 知识点补充