共计 2105 个字符,预计需要花费 6 分钟才能阅读完成。
第二家面试的公司,面试难度不低,面试官更考察我的基础能力,框架的原理什么的很少问。面试官更喜欢抓着你的回答延伸问题,考察你是否真的理解了,好吧我又挂了 = = 哎,很想去这家公司来的,毕竟宅男,还是很喜欢漫画元素的
上题上题
1、下面代码的执行结果
var a = new Object(); | |
a.value = 1; | |
b = a; | |
b.value = 2; | |
console.log(a.value); |
var x = 1; | |
(function() {console.log(x); | |
var x = 2; | |
})() |
var User = { | |
count: 1, | |
getCount: function() {return this.count;} | |
} | |
console.log(User.getCount()) | |
var func = User.getCount; | |
console.log(func()) |
答案
1. 输出 2
我的回答:
var a = new Object(); | |
a.value = 1; | |
b = a; // 这里把 a 赋值给 b 是引用赋值,b 的指针指向了 a 的指针指向 | |
b.value = 2; // 修改 b 的同时就是在修改 a | |
console.log(a.value); // 打印 2 |
知识点:
- js 对象的引用和赋值
- 关于基本类型和引用类型在堆栈中的储存方式
延伸问答:
- 我想改变 b.value 的值,但是 a.value 的值不改变该怎么做?
- 建议了解下堆栈的区别,理解 js 运行的时候函数调用压栈的工作原理?
- 为什么基本数据类型被分配到栈内存,而引用类型要分配到堆内存?
从堆栈区别来理解,基本类型是能确定大小的,因此放在大小确定的堆中(由系统分配、回收),而引用类型无法确定大小,因此放在栈中。
另一篇堆栈区别
2. 输出 undefined
我的回答:
var x = 1; | |
(function() {console.log(x); // var 和 let 区别之一,var 定义的变量会提升,但不会初始化,var x; 因此会打印 undefined | |
var x = 2; | |
})() |
知识点:
- JavaScript 中词法作用域,变量提升的理解
- 立即执行函数 IIFE
- 函数声明的两种方式和如何判断
延伸问答:
var x = 1; | |
(function() {console.log(x); | |
let x = 2; // 会不会报错,为什么 | |
})() | |
var x = 1; | |
(function() {console.log(x); // 输出结果是?为什么?})() |
3. 输出 1 undefined
我的回答:
var User = { | |
count: 1, | |
getCount: function() {return this.count;} | |
} | |
console.log(User.getCount()) // 使用 User 去调用 getCount 函数,此时上下文环境是 User,因此打印 1 | |
var func = User.getCount; | |
console.log(func()) // 在全局环境下调用 func 函数,如果是非严格模式,this 会指向 window 全局对象,找不到 count 这个变量,会打印 undefined |
知识点:
- this 的指向问题
延伸问答:
- 我现在想让
func()
打印出 User 的 count1 怎么办?
var func = User.getCount.bind(User)
- bind 和 call、apply 的区别是?
- 用 apply 实现
bind
2、用 js 实现以下需求
- 一个动物类 Animal,拥有 wow 方法:
console.log(this.name + ":wow"))
- 小狗 Dog 继承 Animal,并且拥有 run 方法:
console.log(this.name + ":run")
// es6 的实现 | |
class Animal {constructor(name) {this.name = name} | |
wow() {console.log(this.name + ":wow") | |
} | |
} | |
class Dog extends Animal {constructor(name) {super(name) | |
} | |
run() {console.log(this.name + ":run") | |
} | |
} | |
// es5 实现 -- 组合继承 | |
function Animal(name) {this.name = name} | |
Animal.prototype.wow = function () {console.log(this.name + 'wow'); | |
} | |
function Dog(name) {Animal.call(this, name) | |
} | |
Dog.prototype = new Animal() | |
Dog.prototype.run = function(name) {console.log(this.name + 'run'); | |
} | |
let d = new Dog('d') | |
d.run() | |
let a = new Animal('a') | |
a.wow() |
3、实现一个闭包的用例?
当时我的回答
const func = function() { | |
var a = 1; | |
return function() {console.log(a); | |
} | |
}()// 函数表达式后面加括号,当 javascript 引擎解析到此处时能立即调用函数 | |
func() |
面试官针对我的回答提问
- 你了解闭包会造成内存泄漏的问题么?从内存角度讲一下你对内存泄漏的影响?如何自动(注意不是手动,
func = null
属于手动)让变量回收?
正文完
发表至: javascript
2019-09-03