JavaScript【五】JavaScript中的对象2

简介: JavaScript【五】JavaScript中的对象

🌟原型:

通过工厂函数与构造函数的方式实例化对象,每实例化一个对象就会重新开辟一片内存空间,造成空间浪费,把公共的属性和方法放在构造函数的原型上,并不会重新开辟空间,节省内存。

原型是构造函数的属性。构造函数.prototype={}

放到原型上的方法与属性,在对象的_ proto _中找到。

🌟原型链:本身->构造函数->构造函数的原型->原型的构造函数的原型->->

访问对象的属性或方法时遵循的链式规则,该属性或方法会在对象本身调用,对象本身没有则去对象本身的构造函数调用,本身构造函数没有则去父类的构造函数调用、父类的原型…以此类推,直到寻找至Object、以及Object的原型、null。最后属性不存在时会得到undefined,方法不存在则会报错。

ject.prototype.say=function(){
     alert("Object的方法");
 }
 function person(){
     this.say=function(){
         alert("person的方法");
     }
 }
 person.prototype.say=function(){
     alert("person原型的方法");
 }
 function student(){
     this.say=function(){
         alert("student的方法");
     }
 }
 student.prototype=new person();
 var xiaoming=new student();
 xiaoming.say=function(){
     alert("xiaoMing的方法");
 }
 xiaoming.say();

🌟对象的继承

继承:一个对象拥有另一个对象的属性与方法

  • 父类(基类):被继承的对象,
  • 子类:继承的对象。

优点:

提高代码的重用性,提高代码的逻辑性与可维护性。

🌟继承方式

  1. 原型继承(将父类的实例作为子类的原型)

原理:对象访问属性方法会遵循 "构造函数 -> 原型"的顺序,所以将父类的实例放到子类原型时, 子类实例化出的对象就可以访问到原型上父类的内容,从而实现了继承。

function Animal(){
    this.age=age;
    this.eat=function(food){
    alert(food)
    }
}
function Cat(){ }
Cat.prototype = new Animal();    // 将父类(Animal)的实例作为子类(Cat)的原型
var tom = new Cat();
cat.eat('fish')     // 弹出 'fish'
console.log(tom instanceof Animal);     //true
console.log(tom instanceof Cat);        //true

call FN.call(obj,参数1,参数2....)

格式:fun.call(obj2,参数1, 参数2…)

本质上来说,call方法实际上就是要改变fun函数内的this指向。

function Animal () {
 this.eat = function(food){
   alert(food)
 }
}
function Cat () {
   this.name = "tom";
}
var animal = new Animal ();
var cat = new Cat ();
animal.eat.call(cat, "鱼")   // 继承单个方法(改变单个方法的this指向)
// 继承整个构造函数 (改变整个构造函数的this指向)
Animal.call(cat);//(方法立即执行)
cat.say("鱼")

apply

用法基本与call相同,函数的参数通过数组传递

格式:fun.apply(obj2,[参数1, 参数2…])

function Animal () {
 this.eat = function(food){
   alert(food)
 }
}
function Cat () {
   this.name = "tom";
}
var animal = new Animal ();
var cat = new Cat ();
animal.eat.apply(cat, ["鱼"])
Animal.apply(cat)
cat.eat("鱼")

bind继承

  • bing用法与 call类似,也是可以改变函数体内 this 的指向
  • call与apply是使用时立即执行函数,
bind

是返回对应函数,便于稍后调用

function Animal () {
this.eat = function(food){
 alert(food)
}
}
function Cat () {
 this.name = "tom";
}
var animal = new Animal ();
var cat = new Cat ();
animal.eat.bind(cat, "鱼")()   // bind只是改变了this指向,想要调用该函数还需()
  1. ES6类继承

通过extends关键字实现类与类之间的继承,然后实例化子类,来实现继承。详见下一节

🌟继承的顺序

优先级:对象本身–>构造函数–>原型链

原型链:

当访问对象的属性或方法时,该属性或方法会在对象本身调用,对象本身没有则去对象本身的构造函数调用,本身构造函数没有则去父类的构造函数调用、父类的原型…以此类推,直到寻找至Object、以及Object的原型、null。最后属性不存在时会得到undefined,方法不存在则会报错。

  Object.prototype.say=function(){
      alert("Object的方法");
  }
  function person(){
      this.say=function(){
          alert("person的方法");
      }
  }
  person.prototype.say=function(){
      alert("person原型的方法");
  }
  function student(){
      this.say=function(){
          alert("student的方法");
      }
  }
  student.prototype=new person();
  var xiaoming=new student();
  xiaoming.say=function(){
      alert("xiaoMing的方法");
  }
  xiaoming.say();

🌟this

this是一个很特别的关键字,被自动定义在所有函数的作用域中。

this总是会指向一个对象。或者说,this就是属性或方法‘当前’所在的对象。


🌟this的指向

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

  1. 在全局环境和全局函数中this指window全局对象。
  2. 作为对象方法调用,this 指代调用该方法对象。
  3. 在构造函数中this指向构造函数的实例
  4. 在事件中,this指向事件源。
  5. 在call和apply中,this指的是方法中传入的对象,如果apply中没有传对象,this指向window
function Fun(){
  run(){
    console.log(this)       // this指向实例化出的对象,因为是实例化出的对象调用了run方法
    setInterval(_=>{
      conosle.log(this)     // this指向 window,因为是window调用了setInterval方法
    })
  }
}

🌟改变this的指向

  • call() ;
  • 第一个参数是this的指向,第二个参数为一个参数列表,会立即执行
  • apply() ;
  • 第一个参数是this的指向,第二个参数为一个参数数组,会立即执行
  • bind()
  • 第一个参数是this的指向,第二个参数为一个参数列表,不会立即执行

🌟ES6对象扩展

🌟属性方法的简洁表示法

当属性名为变量名, 属性值为变量的值时,可直接将变量作为对象的属性:

let username = "张三"
let obj = {
  username,      // 属性名为变量名, 属性值为变量的值
  age: 20
}

对象方法的简写:

let obj = {
run:function(){
  alert(1)
}
}
// 简写为:
let obj = {
run(){
  alert(1)
}
}

这种写法用于函数的返回值,将会非常方便。

function getPoint() {
  const x = 1;
  const y = 10;
  return {x, y};
}
getPoint()

🌟对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
let { first: f, last: l } = { first: 'hello', last: 'world' };
f // 'hello'
l // 'world'

上面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo

如果变量名与属性名一致,可以写成下面这样:

let { foo, bar } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

  • 用途1:接收函数的参数
// 接收被除数x与除数y
function calc({dividend: x, dividend: y}){
return x/y
}
let divide = calc({dividend:9,dividend:3})

用途2:接收函数的返回值

function calc(a,b){
return {
  add: a+b,
  subtract: a-b,
  multiply: a*b,
  divide: a/b
}
}
// 相对于返回数组来讲,不需要知道返回值参数的顺序
let {add, subtract, multiply, divide} = calc(1,2)

🌟对象的Rest属性

ES6中数组的rest和扩展运算符,用于数组于普通参数之间的转化

Math.max(...[1,2,3,4])
function fun(a,b,...c){ }

现在在ES9中,当对象结构复制时也可以使用rest运算符:

let obj = {a: 1, b: 2, c: 3};
let {a,...x}
//  a == 1
//  x == {b: 2, c: 3}


或在函数参数中也可以使用:

restParam({
  a: 1,
  b: 2,
  c: 3
});
function restParam({ a, ...x }) {
  // a = 1
  // x = { b: 2, c: 3 }
}

🌟写在最后

更多JavaScrip知识以及API请大家持续关注,尽请期待。各位小伙伴让我们 let’s be prepared at all times!




目录
相关文章
|
1月前
|
JavaScript 前端开发
JavaScript Date(日期) 对象
JavaScript Date(日期) 对象
35 2
|
24天前
|
存储 JavaScript 前端开发
JavaScript 对象的概念
JavaScript 对象的概念
34 4
|
22天前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
27 1
|
23天前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
14 2
|
25天前
|
JavaScript 前端开发 Unix
Node.js 全局对象
10月更文挑战第5天
19 2
|
29天前
|
存储 JavaScript 前端开发
js中的对象
js中的对象
17 3
|
1月前
|
JavaScript 前端开发
JavaScript Math(算数) 对象
JavaScript Math(算数) 对象
19 4
|
1月前
|
Web App开发 JavaScript 前端开发
JavaScript Window - 浏览器对象模型
JavaScript Window - 浏览器对象模型
20 2
|
1月前
|
JavaScript 前端开发
JavaScript RegExp 对象
JavaScript RegExp 对象
19 3
|
1月前
|
JavaScript 前端开发
JavaScript Boolean(布尔) 对象
JavaScript Boolean(布尔) 对象
17 3