题1
1.1
//js谁调用this,this就指向谁
this.a=20;
var p={
a:30,
test:function(){
alert(this.a);
}
};
p.test();
1.2
//js谁调用this,this就指向谁
this.a=20;
var p={
a:30,
test:function(){
alert(this.a);
}
};
//s -> window
var s=p.test;
s();
1.3
//js谁调用this,this就指向谁
this.a=20;
var p={
a:30,
test:function(){
function s(){
alert(this.a);
}
return s;
}
};
(p.test())();
题2
闭包的内存泄漏
function f1(){
var N=0;
function f2(){
N+=1;
console.log(N);
}
return f2;
}
var result=f1();
result();
result();
result();
打印的值
1
2
3
说明N一直在内存里,从而导致内存泄漏,执行了一次result()时返回函数f2,此时不知道是不是还要执行result函数,所以N一直在内存中,浏览器的垃圾回收机制就不会回收N,要想回收N,设置result=null
题3
请在下面写出JavaScript面向对象编程的混合式继承。并写出ES6版本的继承。 要求:汽车是父类,BMW是子类。父类有颜色、价格属性,有售卖的方法。BMW子 类实现父类颜色是红色,价格是140000,售卖方法实现输出如下语句:将 红色的BMW 买给了小王价格是14万
var Car=function(){
//constructor==Car 构造函数和初始化这个类就是一个东西
}
var s=new Car();
console.log(s);
此时打印的constructor.name为Car
var Car=function(color){
this.color=color;
}
Car.prototype.sail=function(){
console.log(this.color+'色的车卖了13w');
};
var BWM=function(){
}
//按引用传递
BWM.prototype=Car.prototype;
BWM.prototype.test=function(){
}
var s=new Car('red');
console.log(s);
子类BWM继承了Car,但是也改变了父类Car的prototype,多了test方法
var Car=function(color){
console.log(111);
this.color=color;
}
Car.prototype.sail=function(){
console.log(this.color+'色的车卖了13w');
};
var BWM=function(color){
Car.call(this,color);
}
BWM.prototype=new Car();
var m=new BWM('red');
console.log(m);
执行结果
111
111
BWM {color: "red"}
Car里面执行了2次,BWM里面的constructor.name为Car
需要做到
- 拿到父类原型链上的方法
- 不能让构造函数执行2次
- 引用的原型链不能是按址引用
- 修正子类的constructor
var Car=function(color){
console.log(111);
this.color=color;
}
Car.prototype.sail=function(){
console.log(this.color+'色的车卖了13w');
};
var BWM=function(color){
Car.call(this,color);
}
//Object.create原型链的副本
var __pro=Object.create(Car.prototype);
__pro.constructor=BWM;
BWM.prototype=__pro;
var m=new BWM('red');
console.log(m);
题4
(function(){
var a=20;
function a(){
}
alert(a);
})();
函数和变量都会向前提升,函数提升比变量提升多,导致代码变成
(function(){
//函数跑到最前面了
function a(){
}
var a;
a=20;
alert(a);
})();
题5
(function(){
var a=20;
var b=c=a;
})();
alert(c);
根据变量向前提升,得到
var c;
(function(){
var a=20;
var b=20;
c=20
})();
alert(c);
题6
var user={
age:20,
init:function(){
console.log(this.age);
}
}
var data={age:40};
var s=user.init.bind(data);
s.init();
结果
40
题7
function test(m){
m.v=20;
}
var m={age:30};
test(m);
alert(m.v);
对象是按引用传递
<!--html部分-->
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
//js部分
var list_li=document.getElementsByTagName('li');
for(var i=0;i<list_li.length;i++){
(function(i){
list_li[i].onclick=function(){
console.log(i+1);
}
})(i);
}
//或者
var list_li=document.getElementsByTagName('li');
for(var i=0;i<list_li.length;i++){
list_li[i].index=i;
list_li[i].onclick=function(){
console.log(this.index+1);
}
}
//或者
var list_li=document.getElementsByTagName('li');
for(let i=0;i<list_li.length;i++){
list_li[i].onclick=function(){
console.log(i+1);
}
}
总结
- 立即执行函数
- 闭包 内部函数可以访问外部函数的变量,把函数返回出去,闭包可以保护内部的变量 闭包内存泄漏==null
- 原型链
- 构造函数里的属性的优先级比原型链的要高
- 面向对象编程的时候JS没有类的概念 可以用函数代替
- constructor 实际就是对应的那个函数
- prototype 按引用传递的,Object.create原型链的副本
- 构造函数里的属性的优先级比原型链的要高
- 数值 字符串 布尔类型 按值传递,其他都是按引用传递 对象~数组~
- 改变this的方法 call apply bind
- 函数提升 变量提升 函数提升的级别要比变量高
- 异步队列后执行,同步队列先执行
网友评论