JavaScript篇
1、undefined与null的取别
undefined未定义
null定义了但是没有赋值
2、什么时候给变量赋值null
初始赋值
结束回收
3、严格区别变量类型与数据类型?
数据的类型
基本类型
对象类型
变量的类型(变量内存值的类型)
基本类型:保存就是基本类型的数据
引用类型:保存的是地址值
4、问题:在js调用函数时传递变量参数时, 是值传递还是引用传递
理解1:都是值(基本/ 地址值)传递
理解2:可能是值传递,也可能是51用传递(地址值)
<script type="text/javascript">
var a=3
function fn (a) {
a=a+1
}
fn(a)
console.1og(a)
function fn2 (obj) {
console.log( obj.name)
}
var obj = {name: 'Tom'}
fn2(obj)
</script>
5、问题: JS引擎如何管理内存?
1.内存生命周期
*分配小内存空间,得到它的使用权
*存储数据,可以反复进行操作
*释放小内存空间
2.释放内存
*局部变量:函数执行完自动释放
*对象:成为垃圾对象==>垃圾回收器回收
6、测试题1:先执行变量提升, 再执行函数提升
<script>
function a() {}
var a;
console.log(typeof a) // 'function'
if (!(b in window)) {
var b = 1;
}
console.log(b);//undefined
var c = 1;
function c(c) {
console.log(c);//报错
}
c(2);
/* 相当于
var c;
function c(c) {
console.log(c);//报错
}
c = 1
c(2); c不明确
*/
</script>
7、作用域
<script>
//ES6前没有块作用域
if (1) {
var b = 1;
}
console.log(b); //1
var fn = function() {
console.log(fn);//输出整个函数
}
fn();
var obj = {
fn2: function() {
console.log(fn2);//报错(改为this.fn2)
},
}
obj.fn2();
</script>
8、内存溢出&内存泄露
1.内存溢出
* 一种种程序运行出现的错误
*当程序运行需要的内存超过了剩余的内存时,就出抛出内存溢出的错误
2.内存泄露
*占用的内存没有及时释放
*内存泄露积累多了就容易导致内存溢出
*常见的内存泄露:
*意外的全局变量
*没有及时清理的计时器或回调函数
*闭包
```bash
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//代码片段一
var name = "The Window";
var object = {
name: "My object",
getNameFunc: function() {
return function() {
return this.name;
}
}
}
alert(object.getNameFunc()()); //The Window
//代码片段二
var name2 = "The Window";
var object2 = {
name2: "My object",
getNameFunc: function() {
var that = this;
return function() {
return that.name2;
};
}
};
alert(object2.getNameFunc()()); //My object
</script>
</head>
<body>
</body>
</html>
9、οnmοuseenter= “”οnmοuseleave=”" οnmοuseοver="" οnmοuseοut= ””的区别
10、shell函数
11、自增、自减
var n1=10;
var n2=20;
var n = n1++; //n1 = 11 n1++ = 10
console.log('n='+n); // 10
console.log('n1='+n1); //11
n = ++n1 //n1 = 12 ++n1 =12
console.log('n='+n); //12
console.log('n1='+n1); //12
n = n2--;// n2=19 n2--=20
console.log('n='+n); //20
console.log('n2='+n2); //19
n = --n2; //n2=18 --n2 = 18
console.log('n='+n); //18
console.log('n2='+n2); //18
预编译
function fn(a,c){
console.log(a)
var a=123
console.log(a)
console.log(c)
function a() { }
if (false) {
var d=678
}
console.log(d)
console.log(b)
var b = function(){}
console.log(b)
function c() { }
console.log(c)
}
fn(1,2)
this
在函数中直接使用
//##在函数中直接使用
function get (content) {
console.log(content)
}
get('你好')
get.call(window, '你好')//在函数中直接使用,第一个参数是window
函数作为对象的方法被调用(谁调用我我就指向谁)
var person = {
name: '张三',
run: function(time) {
console.log(`${this.name} 在跑步 最多${time}min就不行了`)
},
}
person.run(30)//函数作为对象的方法被调用(谁调用我我就指向谁),run是person对象的方法
person.run.call(person,30)
阿里面试题
var name = 222
var a = {
name: 111,
say: function() {
console.log(this.name)
}
}
var fun = a.say
fun() //222 fun.call(window)
a.say() //111 a.say.call(a)
var b = {
name: 333,
say: function(fun) {
fun()
},
}
b.say(a.say) //222 say.call(window)
b.say = a.say
b.say() //333 b.say.call(b)
箭头函数中的this
●箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定。
●箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有
自己的this,导致内部的this就是外层代码块的this。 正是因为它没有this,所以也就不能用作构造函数。
●箭头函数中的this是在定义函数的时候绑定
var a = 1;
var obj = {
a: 2,
say: () => {
console.log(this.a);
},
}
obj.say();
所谓的定义时候绑定,就是this是继承自父执行 上下文中的this,比如这里的箭头函数中的this.x,箭头函数本
身与say平级以key:value的形式,也就是箭头函数本身所在的对象为obj,而obj的父执行上下文就是
window,因此这里的this.x实际上表示的是window.x,因此输出的是1。
<script type="text/javascript">
var obj = {
birth: 1990,
getAge: function() {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
console.log(obj.getAge())//31
</script>
例子中箭头函数本身是在getAge方法中定义的,因此, getAge方法的父执行上下文是obj,因此这里的this指向则为obj对象
js的作用域,作用域说明:一般理解指一个变量的作用范围
1.全局作用域
(1)全局作用域在页面打开时被创建,页面关闭时被销毁
(2)编写在script标签 中的变量和函数,作用域为全局,在页面的任意位置都可以访问到
(3)在全局作用域中有全局对象window,代表个浏览器窗口, 由浏览器创建,可以直接调用
(4)全局作用域中声明的变量和函数会作为window对象的属性和方法保存
2.函数作用域
(1)调用函数时,函数作用域被创建,函数执行完毕,函数作用域被销毁
(2)每调用次函数就会创建一 个新的函数作用域 ,他们之 间是相互独立的
(3)在函数作用域中可以访问到全局作用域的变量,在函数外无法访问到函数作用域内的变量
(4)在函数作用域中访问变量、函数时,会先在自身作用域中寻找,若没有找到,则会到函数的上-级作用域中寻
找,一直到全局作用域
作用域的深层次理解
+执行期的上下文
-当函数代码执行的前期会创建一个执行期上下文的内部对象AO (作用域)
-这个内部的对象是预编译的时候创建出来的因为当函数被调用的时候会先进行预编译
-在全局代码执行的前期会创建一个执行期的上下文的对象GO
+这里有关js的预编译也简单的提一 下
函数作用域预编译
1.创建ao对象A0{}
2.找形参和变量声明将变量和形参名当做A0对象的属性名值为undef ined
3.实参形参相统一
4.在函数体里面找函数声明值赋予函数体
全局作用域的预编译
1.创建GO对象
2.找变量声明将变量名作为G0对象的属性名值是undefined
3.找函数声明值赋予函数体