JS - 高级

2018-08-13  本文已影响0人  Ht_何甜

JS高级

函数

new关键字

  1. new在执行时会做四件事情:
  2. new会在内存中创建一个新的空对象
  3. new 会让this指向这个新的对象
  4. 执行构造函数 目的:给这个新对象加属性和方法
  5. new会返回这个新对象

this 详解

对象的使用

构造函数

对象的属性和方法叫做对象的成员

  1. 函数内部创建的属性和方法叫做实例对象/对象成员
  2. 跟对象相关的成员,将来使用对象的方式调用
  3. 静态成员:直接给构造函数增加成员
  4. 静态成员不能使用对象的方式调用,使用构造函数调用(Hero.成员)
  5. 实例成员与对象有关,静态成员与对象无关

原型对象

  1. 每个构造函数都有一个属性,就是原型对象prototype
  2. 构造函数通过原型对象增加的方法和属性,构造函数创建的所有对象都可以访问,而且在在内存中只有一份
  3. 对象通过打点的方式增加属性,而 构造函数.prototype 也是一个对象,也可以通过打点的方式增加方法,而且构造函数创建的所有对象都可以增加了这个方法(语法:构造函数.prototype.方法=function(){})
  4. 使用原型对象增加方法和在构造函数内增加方法的区别:当调用对象的属性或方法,先去找对象的属性或方法,如果对象没有该属性/方法,此时去调用原型中的属性或方法
  5. 对象.proto = 构造函数.prototype (通过构造函数(Hero)创建对象(hero1))
  6. 只要有对象,都有proto这个属性,在原型对象中有个属性叫constructor,这个属性叫构造函数,可以打印出这个构造函数,访问方式,对象.constructor,constructor记录了创建给对象的构造函数,可以判断这个对象是由哪个构造函数创建的

构造函数 原型对象 实例/对象 之间的关系

  1. 对象的属性proto 指向 构造函数的原型对象

原型链

  1. 原型链的顶端是null
  2. s1对象的原型对象的原型对象就是Object构造函数的原型对象
    s1.proto.proto===Object.prototype
  3. 读取属性时,先在对象本身查找,找不到就去原型链里找
  4. 设置属性时,不会搜索原型链,而是给这个对象新增一个属性并赋值
  5. 当我们改变构造函数的prototype时,需要重新设置constructor属性
  6. 先设置原型属性,在创建对象,才可以访问原型对象中的成员

原型对象的应用

数组或String中的prototype是不可以重新赋值修改的

继承

面向对象三大特征: 封装 继承 多态(抽象)

继承:类型和类型之间的关系

继承的目的::把子类型中共同的成员提取到父类型中,代码重用

原型继承:无法设置构造函数的参数

借用构造函数(造函数的属性继承)

  1. call()改变函数的this,直接调用函数,call的第一个参数是要改变的指向对象
  2. 在函数内部,通过 call(借用的函数,参数),借用了构造函数继承了属性成员
  3. 借用构造函数的方法只有在构造函数内方法可以继承,通过原型对象增加的方法不能继承

组合继承

  1. 组合继承:借用构造函数+ 原型继承
  2. 借用构造函数(在函数内部使用call) + 原型继承(子类型.protopyte=父类型.prototype)
  3. 借用构造函数,让teacher继承person里的属性,设置teacher的原型对象,继承person里的方法(teache.prototypr=new Person();),

函数的进阶

函数的调用方式

==函数内部的this是由函数调用的时候确定其指向==

call 、apply 和bind()改变函数中的this

function fn(x,y){
    console.log(this);
    console.log(x+y);
}
fn(5,6) //this-->window

var obj={
    name:'zs'
}
fn.call(obj,5,6); //-->obj对象和11
fn.apply(obj,[1,8]);//fn内需要几个参数,数组中传几个参数
//-->obj和9

//bind不会调用函数,要想调用需要用一个变量接收bind的返回值
var f=fn.bind(obj,2,2);
f();//不用传递参数直接调用
  1. 调用函数,改变函数中的this
  2. 第一参数,设置函数内部this的指向,其他参数,对应函数的参数
  3. 函数的返回值,call的返回值就是fn函数的返回值
  1. 调用函数,改变函数中的this
  2. 第一个参数: 设置函数内部this的指向,第二个参数是数组
  3. 函数的返回值,call的返回值就是fn函数的返回值
  1. 改变函数中的this,但不会调用函数,而是把函数复制一份
  2. 第一参数,设置函数内部this的指向,其他参数,对应函数的参数
  3. 函数的返回值,call的返回值就是fn函数的返回值

call的应用

Array.prototype.getSum=function(){
    this指谁?
}
var arr=[1,2,3];
arr.getSum();//通过数组调用,this指向这个数组
arr.push(); //数组本身提供了,push、splice方法
arr.splice(); //删除数组元素  splice(从那一项删除,删除几项)

伪数组

var Obj={
    0:100,
    1:10,
    2,:11,
    3:20,
    length:4
};

给这个数组追加属性:

方法一:

obj['4']=12; //(数字不能作为变量和属性开头,所以用obj['4'])
obj.length++;

方法二:

数组的push方法(让伪数组借用数组的方式)

Array.prototype.push.call(obj,30);
//给Array的原型对象push一个对象,
//并且通过call改变this指向,
//指向obj,就给obj追加了数组

所有的对象都有toString()这个方法

apply的应用

语法:fn.apply(,[])

常用于把数组展开,传递给前面的方法

var arr = [5,8,10,2]
console.log(Math.max(arr))//--.NAN Math.max不能求数组中的最大值
<!--可以把数组中的每一项展开,传给max,返回最大值-->
Math.max.apply(null,arr)
<!--max中的this指向math,所以不用改变指向-->
Math.max.apply(Math,arr)

bind的应用

bind和apply、call的区别在于bind不会去调用方法,而是去复制方法

小结

函数中的其他成员

arguments应用

//当函数的参数个数不固定的时候
//在函数内部,可以通过arguments获取到实际传过来的参数
function max(){
    var max = arguments[0];//假设第一个参数为最大值
    for(var i=0,i<arguments.length;i++){
        if(max<arguments[i]){//如果最大值小于遍历的这个参数
            max=arguments[i];//那么让这个参数为最大值
        }
    }
}
console.log(max(2,7,9,4)); //-->9
上一篇下一篇

猜你喜欢

热点阅读