js面向对象第二天

----------------------------常见的面试问题:数组去重,总结几个,下去敲敲--------------------

最好要用IIEF。

1)双层循环加splice方法

2)indexof去重

3)includes去重

4)利用空对象替换覆盖法

5)利用递归法

。。。

--------------------------------------------------开始今天的内容----------------------------------------

一:原型与原型链

prototype原型:

1)每一个函数都有很多的属性和方法,有一个prototype属性,它对应的value是一个对象,这个对象我们叫做原型对象。

2)原型对象上放了很多的属性和方法

3)每一个原型对象上必定有一个constructor。constructor也是一个属性名,它的value值是当前这个函数(类)本身。

4)每一个对象上都有一个属性__proto__,对应的value是创建这个对象的类的原型对象。

5)这个原型对象里面也有一个__proto__对应的是Object对应的原型对象(基类)。因为object是最顶层的类,也叫基类。

6)所以Object.prototype.__proto__指向它自己。由于指向自己没有任何意义,所以说它的默认值就是null

原型链

如果找一个属性,先在自己内部(私有的)找。

如果有,就使用,不再向后找。

如果没有,就沿着__proto__,找类原型对象上的属性,一直向上找,直到找到Object.prototype为止。

----------------------------------来俩小测题---------------看看有没有被原型链给绕进去

function Func(){
    this.name = "张"
}
let obj1 = new Func();
let obj2 = new Func();

Func.prototype.say = function(){
    console.log("say...")
}
测试题
console.log(obj1.say === obj2.say) 
、、obj1和obj2指向同一块原型对象,里面的方法一致
console.log(Func.prototype.say === obj1.say) 
、、obj1里面没有say,去它的原型对象中找, 它的原型对象指向创建这个对象的类的原型对象
console.log(obj1.__proto__.say === Func.prototype.say)  
、、obj1的原型对象指向创建这个对象的类的原型对象
console.log(obj1.__proto__ === Func.prototype)
、、obj1的原型对象指向创建这个对象的类的原型对象
console.log(obj1.name === obj2.name)
、、两个对象都没有传参,都是undefined,返回true
console.log(obj1 instanceof Func) 
、、func也是一个对象
console.log(obj1 instanceof Object) 
、、类型一致

测试2

var arr1 = new Array("a","b","c")
var arr2 = new Array("d","e","f")
console.log(Array.prototype === arr1.__proto__)
、、Array属于内置对象,内置类,构造函数,arr1的原型对象对应创建它的类的原型对象
console.log(Array.prototype.push === arr1.push)
、、arr1上没有push,会去它的原型对象上去找,所以与它的原型对象上的push相对应
console.log(arr1 === arr2) 
、、arr1与arr2是两块堆,不一样,false
console.log(arr1 instanceof Array) 
。。
console.log(arr1 instanceof Object) 
。。
console.dir(arr1.__proto__)//原型对象 
console.dir(arr1.__proto__.__proto__)//原型对象指向object指向的原型对象,基类
console.dir(arr1.__proto__.__proto__.__proto__)//null

二.难搞的this

关于this的问题,this出现的几个地方

1)在监听器中,this表示事件源

btn事件源,on 前缀,click事件类型

2)在非严格模式下。this出现在普通函数中,表示window,在严格模式下,表示undefined

严格模式:use strict

3)this出现在一个对象的方法中,表示当前这个对象

4)this出现在构造函数中,表示指向一个新的对象

5)在全局变量下,this表示window

this中的精髓:方法中的this指向不确定,谁调用了方法this,这个this就指向谁

一系列的练习题:

(1)

function Func(){
    this.a = 1;
    this.b = 2;
    this.say = function(){
        console.log(this.a)
    }
}
Func.prototype.say = function(){
    console.log(this.b)
}
Func.prototype.jump = function(){
    // 谁调用了jump方法,jump方法中的this就是谁
    console.log(this.a+this.b)
}
let wc = new Func();
wc.jump();   // 3

(2)

function Func(){
    this.a = 1;
    this.b = 2;
    this.say = function(){
        console.log(this.a)
    }
}
Func.prototype.say = function(){
    // 谁调用了say这个方法,那么this就是谁
    // wc.__proto__ 
    console.log(this.b)
}
Func.prototype.jump = function(){
    console.log(this.a+this.b)
}
let wc = new Func();
// 明确指出调用原型对象上的方法
// wc.__proto__ 它调用了say方法,那么这个方法中的this就是wc.__proto__
wc.__proto__.say();  // undefined

(3)

function Func(){
    this.a = 1;
    this.b = 2;
    this.say = function(){
        console.log(this.a)
    }
}
Func.prototype.say = function(){
    console.log(this.b)
}
Func.prototype.jump = function(){
    // 此时this表示wc.__proto__
    console.log(this.a)  // undefined
    console.log(this.b)  // undefined
    console.log(this.a+this.b)  // NaN
}
let wc = new Func();
wc.__proto__.jump(); // NaN

三.关于匿名函数的一些问题

1)var f =function(){},这是把一个匿名函数赋值给了f。

对于上面的匿名函数表达式,可以给这个匿名函数,指定函数名g。。

var f = function g(){console.log("haha...")}

 f()

g()//会打印出, g is not defined

//前面我们讲过,不能通过函数表达式的函数名来调用,所以只能通过f(),不可以g().

2)那怎么使用匿名函数名?那就在它自己的函数体中使用

举个例子:

var f = function g(){
   console.log(g) // g是函数名,可以在函数体中使用
    g();  // 可以通过g()调用这个函数,但是没有出口会死循环
  g = 1;  // 把基本数据类型赋值给g没有作用
 g = []; // 引用数据类型赋值给g也没有作用
  g = {};
   g = function(){
        console.log("xixi...")
   }
    console.log(g)
}
 f()

总结匿名函数名注意事项:

1)匿名函数名可以在函数体中使用

2)可以直接调用,但是没有出口会死循环

3)不能重新赋值,基本数据类型和引用数据类型都不可以

4)综上所述:对于函数表达式来说,它可以有函数名,它可以在内部调用,不能再外部通过函数名调用!

-----------------------------------------来俩例子练练---------------------------

(1)

var a = function abc(num) {
    abc = num;
    console.log(num)   
    console.log(abc)  
    console.log(typeof abc) 
}
 a(1)

(2)

var a = function abc(num) {
    abc = num;
     return 1;
 }
 a(1)
 console.log(abc())

四.关于this的练习请找下篇面试题总结this(有点多)。。

 

猜你喜欢

转载自blog.csdn.net/zwy1231/article/details/103487080
今日推荐