请回答以下问题
Java和JavaScript什么关系?
1 | 最初的 JavaScript 名为 LiveScript,后来因为 Sun Microsystem 的 Java 语言的兴起和广泛使用,Netscape 出于宣传和推广的考虑,将它的名字从最初的 LiveScript 更改为 JavaScript——尽管两者之间并没有什么共同点。这便是之后混淆产生的根源。 |
ES6听说过吗?和JavaScript什么关系?ES2015听说过吗?都是什么关系?
1 | ES6是JavaScript的第六版,因为在2015年发布,所以也称ES2015 |
如何把变量转成数字?转成布尔?转成字符串?
1 | 转数字 |
使用 Number() 和 parseInt 转数字时的区别?
1 | 如上... |
var 和 let 干什么用的?什么区别?
1 | 都是定义变量的 |
在一个函数中,如果定义变量时没有添加 var 会出现什么情况?
1 | 如果在函数中定义变量时没有写 var 或者 let 那么变量会变成全局变量。 |
什么是内存泄漏?
1 | 应该当作垃圾回收结果无法被释放,导致一直占用内存。这种行为被成为内存泄露 |
什么是块级作用域?如何定义块级作用域的变量?
1 | 在大大括号内的,一般用let定义块级变量 |
你需要带着问题,看下面的内容
什么是运算符短路?有什么用?
说出JS中你用过的数据类型?
编写一个使用 let 定义变量和使用 var 定义变量不同点的案例。
for .. in 和 for .. of 的区别?用途?
forEach 的用途?
请问 arguments 是干什么用的?它代表什么?
什么是匿名函数?应用场景?
this 代表什么?
什么是箭头函数?有什么用途?this 在箭头函数和普通函数中的区别是什么?
call 和 apply 的功能是什么?有什么区别?
如何开启严格模式?请说出至少一个严格模式与普通模式的区别?
什么是闭包?闭包有什么特点?有什么用?
什么是垃圾回收机制?
什么是内存泄漏?在什么情况下会出现内存泄漏?
什么是OOP?OOP的三大特性?什么是多态?
什么是原型链?对象如何访问原型对象?构造函数如何访问原型对象?
什么是构造函数?在JS中如何基于原型(prototype)实现面向对象?
ES6中的OOP中 super 是干什么用的?ES6中的继承需要注意什么?
介绍
数据类型
类型转换
转数字
parseInt:如果前几个字符是数字可以转成数字。
Number:将整体转成数字。
1 | var num = '123abc'; |
转字符串
1 | console.log( 100 + 100 + '100abc'); // 200100abc |
变量
定义变量:var
和 let
。
定义常量:const
。
var
可以定义 局部变量
和 全局变量
。
1 | var name; // 全局变量 |
意外的全局变量。
如果在函数中定义变量时没有写 var
或者 let
那么变量会变成全局变量。
1 | function abc() { |
let
可以定义块级变量
、 局部变量
和 全局变量
。
let 可以定义块级变量(只在大括号中生效的变量)
示例1:let 和 var 的区别
1 | for(let i=0;i<10;i++) { |
示例2:使用 var 时无论,调用数组中第几个函数,输出的结果都是10
1 | var funs = [] |
使用 let 时的效果:
1 | var funs = [] |
短路运算符
我们可以使用 &&
和 ||
实现短路操作。
&& : 连接多个语句,当语句1为真是执行语句2.
||:连接多个语句,当语句1为假时执行语句2.
可以用短路运算符来实现一些简写,比如,有时我们获取到一个变量,不知道它的值是什么,但我们希望无论如何它都是一个数字,至少是个0,我们就可以写:
1 | // 如果 a 是假就得到0 |
1 | // 如果 o 存在就调用 o.name |
循环
除了 while、do…while、for 之外,我们还可以使用:
在循环数组时,我们可以使用
for...of
、for...in
、forEach
。循环对象时,我们可以使用
for...in
。
1 | let arr = ['a','b','c','d','e'] |
函数
arguments
在函数中可以使用 arguments
获取函数在调用时的参数数组。
1 | function abc() { |
匿名函数
匿名函数可以用来隔绝一段作用域。
有时我们需要在一个现有的项目中添加新的代码,这时当我们添加变量、函数时就有可能出现和原来系统中变量名、函数名冲突的情况,为了避免我们的代码和原代码中出现命名冲突的情况,我们就可以把我们的代码放到一个匿名函数中,然后调用这个匿名函数,这样我们所写的代码都只在这个匿名函数内生效,就不会影响其它代码了。
有两种写法,来调用匿名函数得到一段独立的作用域:
1 | (function(){ |
箭头函数
箭头函数是匿名函数的一种简写方式。
1 | // 普通函数 |
比如以下代码运行的结果是不同的:
1 | var age = 20 |
call/apply
call 和 apply 的功能相同:使一个函数归属于一个对象来调用
。
1 | function abc() { |
call 和 apply 的区别是参数形式不同:
1 | function abc(a,b) { |
严格模式
以下代码在严格模式下会报错:
1 | // 严格模式 |
闭包
以下代码就是一个闭包,它制作了一个 id 变量,这个变量不会马上销毁,会一直存在,并且不能被外部随意修改,只能通过闭包内修改。
1 | // 定义闭包 |
内存泄漏
循环引用
当 DOM 对象和 JS 对象互相引用时,会导致两个对象在该销毁时都无法销毁。
比如下面的 el 和 o 这两个对象都是局部变量,在函数执行之后就应该销毁,但因为两个对象互相引用,所以导致函数执行之后也无法销毁:
原型链
原型链:所有的对象都会继承自一个原型对象,这个原型对象又会继承自一个原型对象,一层一层直到最顶层继承自 null,这样的链就是原型链。
构造函数:生成对象的函数。
访问原型对象
对象中通过 __proto__
访问原型对象。
构造函数中通过 prototype
访问原型对象。
基于原型链的面向对象
JS 在实现面向对象编程时传统的方法是基于原型链+构造函数。
1 | // 定义一个类 |
JS 中实现面向对象编程的原则:
- 属性定义到构造函数中
- 方法定义到原型对象上(避免每个对象都拷贝一份函数)
ES6 中的面向对象
ES6 中提供了 class
可以实现面向对象。
1 | class Person |
继承
在原型统的 JS 中我们使用原型对象实现继承,在 ES6 中我们可以使用 extends
实现类的继承。
1 | class Person |
super
在继承时,如果子类中定义了构造函数,那么在构造函数中必须要调用 super
方法来调用父类的构造函数。
~js
class Person
{
// 构造函数
constructor(name,age) {
this.name = name
this.age = age
}
getName() {
return this.name
}
setName(name) {
this.name = name
}
}
// 继承自 Person
class Boy extends Person {
constructor(name, age) {
// 调用父类的构造函数
super(name, age)
}
}