日记8.19

学习日记

1.明天开始更新游戏相关新闻以及游戏黑神话悟空的攻略或者分享吧,太激动了。关注了4年了,终于能和它见面了!!!
2.今天完成了ae的杂色和颗粒,扭曲与过渡效果的学习,可以制作背景流动板效果,至此为止,已经将AE的所有基础内容学习完成,接下来要投入相关效果的制作和学习。
2.完成了js的一些面试题学习。

2024.8.19

js对象考题

1
2
3
4
5
6
1.对象是通过new操作符构建出来的,所以对象之间不相等;
2.对象要注意引用类型,引用类型取地址,所以会得出相等的答案;
3.对象中的key都是字符串类型;
4.对象是如何找属性|方法:(原型链)
先在对象的本身找->在构造函数找->对象的原型上找->构造函数的原型上找->对象上一层原型上找->...->最后找到object

1
2
3
4
5
6
7
8
9
10
var a ={}
var b ={
key:'b'
}
var c = {
key:'c'
}
a[b]='123'; //这里的b,c最终在a里面都是[object object]所以可以看作是相同的key所以越后面赋值就能替换掉前面的赋值。
a[c]='456';
console.log(a[b]) //输出456

js作用域+this指向+原型考题

考题1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    function Foo(){
getName = function(){console.log(1)} //这是全局的window.声明变量
return this;
}

Foo.getName = function(){console.log(2)}
Foo.prototype.getName = function(){console.log(3)}
var getName = function(){console.log(4)}
function getName(){
console.log(5)
}

Foo.getName(); //2 Foo没有括号不是调用Foo函数
getName(); //4 //变量作用域优先于函数

//注意看这里Foo函数返回了this,这里相当于执行了一句话 window.getName()
// 执行内容:①Foo()---> getName = function(){console.log(1)}创建了全局的getName对象
// 覆盖前者var getName = function(){console.log(4)} 返回的this指代window
// ②window.getName()---> 执行function(){console.log(1)}
Foo().getName(); //1
getName(); //1
new Foo().getName(); //3
/* 先在对象的本身找->在构造函数找->对象的原型上找->
构造函数的原型上找->对象上一层原型上找->...->最后找到object */

考题2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//涉及到了this的指向和函数是否执行
window.name = '你好';
function A(){
this.name = 123;
}
A.prototype.getA = function(){
console.log(this);
return this.name+1;
}

let a = new A();
let funA = a.getA; //注意看没有括号所以相当于返回了个函数体并未执行
console.log(funA()); //结果:你好1

考题3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//涉及到了闭包,作用域,this指向
var len = 10;
function fn(){
return this.len + 1;
}
var obj = {
len:6,
test1:function(){
return fn();
}
}
obj.test2=fn; //赋予了函数体未执行函数
console.log(obj.test1()); //11 此时执行的test1函数return是函数形成了闭包,那么this指向的是window

/* 此时obj中:
test2:function(){
return this.len + 1;
}
*/
console.log(fn()===obj.test2()); //false 11和6


console.log(obj.test1()===obj.test2()); //false

js数组去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//1.内置封装函数set()去重
var a = [1,1,4,2,2,3]
let b = [...new Set(a)]
console.log(b)

//2.构建哈希表去重
var arr = [1,1,4,2,2,3]
var brr = []
for(var i = 0;i<arr.length;++i){
if(!brr.includes(arr[i])){
brr.push(arr[i])
}
}
console.log(brr)

闭包

1
2
3
4
5
6
7
8
9
10
1.闭包是什么
闭包是一个函数加到创建函数作用域的连接,闭包它会关闭函数的自由变量

2.闭包可以解决什么问题呢?【闭包的优点】
内部函数可以访问到外部函数的局部变量,闭包可以解决如下代码所示问题。

3.闭包的缺点
①变量会驻留在内存中,造成内存损耗问题。
解决方法:把闭包函数设置为null。
②内存泄漏问题(仅在ie出现)
1
2
3
4
5
6
7
8
9
10
11
12
//闭包可以解决的问题

//让各个li元素在点击的时候显示其索引值
var lis = document.getElementsByTagName('li');
for(var i = 0;i<lis.length;++i){
//这种情况下每个i不会被释放,而是保存在内存当中
(function(i){
lis[i].onclick=function(){
alert(i);
}
})(i)
}

找出二维数组最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fnArr(arr){
var newArr=[];

arr.forEach((item,index)=>{
newArr.push(Math.max(...item))
})
return newArr;
}

console.log(fnArr([
[4,6,7,5],
[13,5,78,41],
[58,0,64,7]
]))

new操作符具体做了些什么

1
2
3
4
1.创建了一个空对象
2.将空对象的原型,指向于构造函数的原型
3.将空对象作为构造函数的上下文(改变this指向)
4.对构造函数有返回值的进行处理判断(返回基本类型new会忽略,但返回的是引用类型的话new会改变原返回值)
1
2
3
4
5
6
4点相关例子:
function Foo(){
this.name = '张三'
return [1,2,3];
}
console.log(new Foo()); //返回了数组[1,2,3]

原型链是什么?

1
2
3
4
5
6
7
8
9
10
11
讲到原型链,那就得先讲一下原型的设计初衷。原型的设计是为了能够解决对象共享属性和方法的问题。

其中函数拥有prototype,对象拥有__proto__

对象查找方法和属性的顺序:
对象本身==》构造函数==》对象原型==》构造函数原型==》当前原型=》原型的原型...

把原型串联起来,这样就形成了原型链

原型链最顶端是null