1.构造函数

1.1 对象

某一类事物的具体实例

1.2 类

对某一具体事物的抽象

1.3 构造函数

1.3.1 实例

实例: new 出来的对象

1.3.2 构造函数的缺点

同一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。

  1. /* 公有的属性或者公有的方法我们可以放在原型对象上 */
  2. function Person(name,age){
  3. this.name = name
  4. this.age = age
  5. }
  6. Person.prototype.eat = "水果"
  7. var p = new Person("li",19)
  8. var zhang = new Person("zhang",20)
  9. console.log(p);
  10. console.log(zhang);

1.3.3 构造函数

  1. 构造函数:构造一个类(对象)的函数
  2. 构造函数的特点:
  3. 1.首字母大写
  4. 2.函数内部使用this关键字,谁new(实例化)就指向谁
  5. 3.使用this关键字给对象添加属性
  6. 4.必须使用new关键字,去生成一个对象
  1. // 在 javascript 中新建一个类 使用构造函数
  2. function Student(name,age){
  3. this.name = name;
  4. this.age=age
  5. }
  6. /* this 指实例化的对象 */
  7. /* 实例 */
  8. var zheng = new Student("zcy",18)
  9. console.log(zheng);
  10. // 读取对象的属性
  11. console.log(p.name);
  12. console.log(p.age);

1.3.4 instanceof 判断一个对象是不是某个类的实例

  1. var arr = [1,2,3]
  2. console.log(arr instanceof Array); // true
  3. function Person(name,age){
  4. this.name = name
  5. this.age = age
  6. }
  7. var p = new Person("zheng",18)
  8. console.log(p instanceof Person); // true

2.原型

2.1 原型

  1. # JS的继承是基于原型的继承
  1. /* 原型
  2. 1.obj.__proto__ 找到它的原型对象
  3. 2.数组上的方法都是挂载在原型上(Array.prototype)的
  4. */
  5. // toString() 因为数组的原型上有字符串toString()
  6. // push,unshift() 因为数组原型上有
  7. var arr = [1,2,3]
  8. console.log(Array.prototype);
  9. console.log(arr.__proto__);
  10. console.log(arr.__proto__ == Array.prototype);

2.2 原型对象作用

  1. # 原型对象:是某一类对象的基类,所有创建的对象都会共享该原型对象 (共享机制)
  2. # 作用:将对象通用的方法挂载在原型上
  1. var arr = [1,2,3]
  2. Array.prototype.sum = function(params){
  3. if(Array.isArray(params)){
  4. return params.reduce((a,b)=>a+b)
  5. }
  6. }
  7. console.log(arr.sum(arr));
  8. Array.prototype.http = function(){
  9. console.log("http");
  10. }
  11. arr.http()

image.png

  1. function Teacher(name,age){
  2. this.name = name
  3. this.age = age
  4. }
  5. /* sayName */
  6. Teacher.prototype.sayName = function(){
  7. console.log(this.name);
  8. }
  9. var p = new Teacher("lisi",30)
  10. console.log(p);

3.原型链

image.png

  1. var arr = [1,2,3]
  2. console.log(arr.__proto__);
  3. console.log(arr.__proto__ == Array.prototype);
  4. console.log(arr.__proto__.__proto__)
  5. console.log(arr.__proto__.__proto__ == Object.prototype)
  6. console.log(arr.valueOf());

QQ图片20201208192502.png

4、构造属性

4.1 构造属性

  1. ## 创建构造函数的时候,原型对象上会有一个constructor属性,它是原型对象所独有的,它指回构造函数本身

image.png

  1. function Person(name,age){
  2. this.name = name
  3. this.age = age
  4. }
  5. var p = new Person("cheng",20)
  6. console.log(p.constructor);
  7. console.log(p.constructor == Person); // true
  8. var arr = [1,2,3]
  9. console.log(arr.constructor == Array); // true

4.2 给原型添加属性 ( 直接量形式 )

  1. # 问题:我们以直接量(对象)形式,给原型添加属性的时候,它的constructor会指向Object
  2. # 解决:重置 constructor
  1. function Person(name,age){
  2. this.name = name
  3. this.age = age
  4. }
  5. Person.prototype = {
  6. sayName:function(){
  7. console.log(this.name);
  8. },
  9. sayAge(){
  10. console.log(this.age);
  11. }
  12. }
  13. var p = new Person("cheng",20)
  14. console.log(p.constructor); //Object
  15. console.log(p.constructor == Person); // false
  16. console.log(p instanceof Person); // true
  17. ## 解决办法
  18. Person.prototype = {
  19. constructor:Person, // 重置 constructor
  20. sayName:function(){
  21. console.log(this.name);
  22. },
  23. sayAge(){
  24. console.log(this.age);
  25. }
  26. }
  27. var p = new Person("cheng",20)
  28. console.log(p.constructor); // Person
  29. console.log(p.constructor == Person); // true

4.3 公有属性和私有属性

  1. # 公有属性: 一般在原型对象上
  2. # 私有属性: 通过this关键字去添加的
  3. # hasOwnProperty 可以判断属性是私有的还是公有的
  1. function Person(name,age){
  2. this.name = name
  3. this.age = age
  4. }
  5. Person.prototype = {
  6. constructor:Person,
  7. sayName:function(){
  8. console.log(this.name);
  9. },
  10. sayAge(){
  11. console.log(this.age);
  12. }
  13. }
  14. var p = new Person("cheng",20)
  15. console.log(p.hasOwnProperty("name")); // true 私有的
  16. console.log(p.hasOwnProperty("sayName")); // false 公有的
  17. //判断constructor是否是原型对象的私有属性
  18. console.log(Person.prototype.hasOwnProperty("constructor")); // true

5.函数内部this指向

5.1 函数中this指向

  1. 函数正常调用的时候this指向: window
  2. 定时器: window
  3. 构造函数:实例化对象
  1. var name = "张三"
  2. function show(){
  3. console.log(this.name);
  4. }
  5. function go(){
  6. var name = "李四"
  7. show()
  8. }
  9. go() // "张三" // window.go()
  10. function go(){
  11. var name = "李四"
  12. console.log(this.name); // window.name
  13. }
  14. go() // "张三" window.go()

5.2 改变函数中this指向

5.2.1 call

语法: funName.call(obj,arg1,arg2...)

  1. var name="王五"
  2. var obj = { name:"李四" }
  3. function go(){
  4. console.log(this.name);
  5. }
  6. go() // 王五
  7. go.call(obj) // 李四

5.2.2 apply

语法:funName.call(obj,[arg1,arg2...])

  1. callapply的区别:
  2. 应用场景:传递多个参数的情况
  3. call依次去传递
  4. apply 需要传递数组
  1. var name="window"
  2. var zhang={
  3. name:"张三"
  4. }
  5. function show(a,b){
  6. console.log(this.name);
  7. console.log(a+b);
  8. }
  9. show(1,2)
  10. show.call(zhang,2,3)
  11. show.apply(zhang,[1,2])

5.2.3 bind

  1. bind 绑定的函数不会马上执行,只是改变了函数上下文的执行环境
  2. callapply调用的时候马上执行
  1. var name = "window"
  2. var zhang = {
  3. name:"张三"
  4. }
  5. var show = function (a,b){
  6. console.log(this.name);
  7. console.log(a+b);
  8. }.bind(zhang)
  9. show(2,3) // zhang 5

5.2.4 使用场景

  • 解决定时器中this的指向问题 ```javascript

解决

1.使用bind解决

btn.onclick = function(){ setTimeout(function(){
console.log(this.id);
}.bind(btn),1000) }

/* btn.onclick = function(){ var self = this setTimeout(function(){
console.log(this.id);
}.bind(self),1000) }

btn.onclick = function(){ setTimeout(function(){
console.log(this.id);
}.bind(this),1000) } */

2.使用箭头函数解决

btn.onclick = function(){ setTimeout(()=>{ console.log(this.id); },1000) }

  1. <a name="MezJv"></a>
  2. ## 6.继承
  3. <a name="Wh51z"></a>
  4. ## Javascript的继承是基于原型的继承
  5. <a name="m6q9m"></a>
  6. ### 6.1 属性的继承
  7. ```javascript
  8. # call 实现属性的继承
  1. function Person(name,age){
  2. this.name = name;
  3. this.age = age
  4. }
  5. function Teacher(name,age,skill){
  6. Person.call(this,name,age) // Person(name,age)中的this指向window,需要改变this指向
  7. this.skill = skill // this指向 Teacher构造函数的实例对象
  8. }
  9. var t = new Teacher("zhang",18,"js")
  10. console.log(t);

6.2 方法的继承

  1. function Person(name,age){
  2. this.name = name;
  3. this.age = age
  4. }
  5. Person.prototype.sayName = function(){
  6. console.log(this.name);
  7. }
  8. function Teacher(name,age,skill){
  9. Person.call(this,name,age)
  10. this.skill = skill
  11. }
  12. Teacher.prototype = Person.prototype
  13. Teacher.prototype.constructor = Teacher
  14. Teacher.prototype.sayAge = function(){
  15. console.log(this.age);
  16. }
  17. var t = new Teacher("zhang",18,"js")
  18. console.log(t);
  19. t.sayName()
  20. t.sayAge()

6.2.1 es5中实现继承的方法

  1. function Person(name,age){
  2. this.name = name;
  3. this.age = age
  4. }
  5. Person.prototype.sayName = function(){
  6. console.log(this.name);
  7. }
  8. function Teacher(name,age,skill){
  9. Person.call(this,name,age)
  10. this.skill = skill
  11. }
  12. Teacher.prototype = Object.create(Person.prototype,{
  13. constructor:{
  14. value:Teacher
  15. }
  16. })
  17. Teacher.prototype.sayAge = function(){
  18. console.log(this.age);
  19. }
  20. var t = new Teacher("zhang",18,"js")
  21. console.log(t);
  22. console.log(t.constructor);
  23. t.sayName()
  24. t.sayAge()