1.立即执行函数
如字面意思,声明一个函数然后立即执行
(function(){alert('我是匿名函数')} ()) // 用括号把整个表达式包起来
(function(){alert('我是匿名函数')}) () // 用括号把函数包起来
!function(){alert('我是匿名函数')}() // 求反,我们不在意值是多少,只想通过语法检查。
+function(){alert('我是匿名函数')}()
-function(){alert('我是匿名函数')}()
~function(){alert('我是匿名函数')}()
void function(){alert('我是匿名函数')}()
new function(){alert('我是匿名函数')}()
var x = function(){return '我是匿名函数'}()
解决了什么问题:
在 ES6 之前,只能通过它来「创建局部作用域」。
2.闭包
一种语法特性
闭包=函数+自由变量
自由变量:有自己作用域的变量(相对的就是全局变量)
{
let count
function add (){ // 访问了外部变量的函数
count += 1
}
}
闭包
解决了什么问题:
- 避免污染全局环境。(因为用的是局部变量)
- 提供对局部变量的间接访问。(因为只能 count += 1 不能 count -= 1)
- 维持变量,使其不被垃圾回收。
优点:
简单,好用。
缺点:
闭包使用不当可能造成内存泄露。
注意,重点是「使用不当」,不是闭包。
3. js实现类
1.使用原型
function chicken(){
}
chicken.prototype.kind = '鸡'
chicken.prototype.say = () =>{console.log('打鸣')}
chicken.prototype.fly = () =>{console.log('扑腾')}
const c = new chicken()
c.say()
c.fly()
console.log(c.kind)
2.使用class
class chicken{
constructor() {
this.name = name
}
say(){console.log('打鸣')}
fly(){console.log('扑腾')}
}
const c = new chicken()
c.say()
c.fly()
console.log(c.kind)
以我大学的学习习惯来说当然是经常使用2,但是1的话只要理解了原型链也是非常简单易懂的
4.继承
1.使用原型链
function Animal(legsNumber){
this.legsNumber = legsNumber
}
Animal.prototype.kind = '动物'
function Dog(name){
this.name = name
Animal.call(this, 4) // 关键代码1
}
Dog.prototype.__proto__ = Animal.prototype // 关键代码2,但这句代码被禁用了,怎么办
Dog.prototype.kind = '狗'
Dog.prototype.say = function(){
console.log(`汪汪汪~ 我是${this.name},我有${this.legsNumber}条腿。`)
}
const d1 = new Dog('啸天') // Dog 函数就是一个类
console.dir(d1)
如果面试官问被 ban 的代码如何替换,就说下面三句:
var f = function(){ }
f.prototype = Animal.prototype
Dog.prototype = new f()
2.使用 class
class Animal{
constructor(legsNumber){
this.legsNumber = legsNumber
}
run(){}
}
class Dog extends Animal{
constructor(name) {
super(4)
this.name = name
}
say(){
console.log(`汪汪汪~ 我是${this.name},我有${this.legsNumber}条腿。`)
}
}