【javascript】进阶语法【上】

目录

一、构造函数和原型

二、js的成员查找机制(规则)

三、组合继承:构造函数+原型对象

借用构造函数继承父类型的属性

借用原型对象继承父类型方法

四、ES5新增的方法

1.数组方法

some、forEach、filter的区别

2.字符串方法

3.对象方法

五、函数的定义和调用

1.函数的定义

2.函数的调用和this指向

3.改变函数内部this指向

4.call apply bind的比较


一、构造函数和原型

静态成员

                构造函数本身上添加的成员,只能通过构造函数来访问,不能通过对象来访问

实例成员    

                构造函数通过this添加的成员,只能通过实例化的对象来访问,不可以通过构 造函数来访问实例成员


构造函数原型prototyoe

        ①构造函数通过原型分配的函数是所有对象所共享的

        ② 每个函数都有一个prototype属性,指向另一个对象。注意这个prototype就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有

        ③我们可以把那些不变的方法,直接定义在prototype对象上,这样所有的对象的实例就可以共享这些方法

        一般情况下,我们的公共属性定义到构造函数里面,公共方法我们放到原型对象身上        


   __proto__对象原型  

        ① 对象都有一个属性__proto__指向构造函数的prototype原型对象,之所以对象可以使用构造函数Prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在。

        ②__proto__对象原型和原型对象prototype是等价的

        ③__proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,他只是内部指向原型独享prototype

        方法查找规则:先查看对象身上有没有该方法,有就执行,没有这个方法,因为有__proto__的存在,就去构造函数原型对象身上prototype身上查找这个方法

注意:

        每个原型对象也都有属性__proto__,它指向Object构造函数的原型对象

        Object构造函数的原型对象的属性__proto__,它指向null


constructor构造函数

        ①对象原型(__proto__)和构造函数(prototype)原型对象里面都有一个属性constructor属性,constructor我们称为构造函数,因为它指回构造函数本身

        ②constructor主要用于记录该对象引用于哪个构造函数,它可以让原型对象重新指向原来的构造函数

         ③很多情况下,我们手动利用constructor这个属性指回原来的构造函数

       ④如果我们修改了原来的构造函数,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数


        构造函数、实例、原型对象三者之间的关系

          原型链


二、js的成员查找机制(规则)

        ①当访问一个对象的属性(包括方法)时,首先查找这个对象那个自身有没有该属性

        ②如果没有就查找它的原型(也就是__proto__指向的prototype原型对象)

        ③如果还没有就查找原型对象的原型(Object的原型对象)

        ④依次类推一直找到Object为止(null)

        ⑤__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

        

    原型对象的this指向实例对象

扩展内置对象

           可以通过原型对象,对原来的内置对象进行扩展自定义方法,比如给数组添加自定义求偶数和的功能

        注意:数组和字符串内置对象不能给原型对象覆盖操作Array.prototype={},只能是Array.prototype.xxx=function(){}的方式


三、组合继承:构造函数+原型对象

借用构造函数继承父类型的属性

        核心原理:通过call()把父类型的this指向子类型的this,这样就可以实现子类继承父类型的属性

function Father(uname,age){
    this.uname=uname;
    this.age=age;
};
function Son(uname,age,score){
    //此时这个Father构造函数里面的this指向Son构造函数中的this
    Father.call(this,uname,age);//这个this表示son构造函数中的this,指向Son的实例对象
    this.score=score;
};
var son=new Son('lisi',19,100);
console.log(son.uname);//lisi
console.log(son.age);//19
console.log(son.score);//100

借用原型对象继承父类型方法

        ①将父类的原型对象赋值给子类的原型对象

                    存在问题:当想要给子类的原型对象添加独有的方法时候,父类也会有该方法,因为子原型对象指向父原型对象,此时子原型对象改变会影响父原型对象

function Father(){

};
Father.prototype.sing=function(){
    console.log('我会唱歌');
}
function Son(){

}
//存在问题,以下是引用类型赋值,传递的是地址,
// 当某一个改变,则另一个也要改变
//当给Son声明一个单独特殊的money方法时,Father也有了该方法,
// 所以这导致无法给子类添加特殊的方法
Son.prototype=Father.prototype;
Son.prototype.money=function(){
        console.log('一百元');
    }
var father=new Father();
var son=new Son();
console.log(son.sing());
console.log(father.money());

        ②将实例化父构造函数赋值给子类的原型对象

                   因为上面是通过对象形式修改了原型对象,所以下一步要利用constructor指回原来的构造函数

function Father(){

};
Father.prototype.sing=function(){
    console.log('我会唱歌');
}
function Son(){

}
//将子类的原型对象指向父类的实例对象
// 再将子类原型对象的constructor指向子类的构造函数
Son.prototype=new Father();
Son.prototype.constructor=Son;

Son.prototype.money=function(){  //子类独有的方法
        console.log('一百元');
    }

var son=new Son();

console.log(son.sing());

四、ES5新增的方法

1.数组方法

迭代(遍历)方法:forEach()、map()、filter()、some()、every()

array.forEach(function(currentValue,index,arr))

currentValue:数组当前项的值

index:数组当前项的索引

arr:数组对象本身

总是返回undefined

注意:forEach()对于空数组是不会执行里面的回调函数function

array.filter(function(currentValue,index,arr))

currentValue:数组当前项的值

index:数组当前项的索引

arr:数组对象本身

注意:filter()方法创建一个新数组,新数组的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组,它返回的是一个新数组

array.some(function(currentValue,index,arr))

currentValue:数组当前项的值

index:数组当前项的索引

arr:数组对象本身

注意:some()方法用于检测数组中的元素是否满足指定条件,查找数组中是否有满足条件的元素,它返回的是布尔值,如果找到,返回true,找不到返回false

找到第一个满足条件的元素,就终止循环,不再继续查找

如果查询数组中唯一的元素,用some方法更合适


some、forEach、filter的区别

forEach的return不会终止迭代  return true 和return false都类似continue

some的return会终止迭代   return true 类似break   return false类似continue

filter的return不会终止迭代    return true 和return false 都类似continue

2.字符串方法

str.trim()

trim()方法会从一个字符串的两端删除空白字符

并不影响原字符串本身,它返回的是一个新的字符串

3.对象方法

Object.keys(obj)

用于获取对象自身的属性

效果类似for...in

返回一个属性名组成的数组

Object.defineProperty(obj,prop,descriptor)

定义新属性或修改原有的属性

obj:目标对象

prop:需定义或修改的属性名字

descriptior:目标属性所拥有的特效  

          书写方式:对象形式,

          有关属性:

                       value  值  默认是undefined

                       writable  true或false  //表示是否可修改这个属性值  默认是false

                      enumerable:  true或false  //表示是否可枚举   默认是false

                      configurable:  true或false  //表示是否可被删除或是否可以再次修改特性 默认是false


五、函数的定义和调用

1.函数的定义

  1. 函数声明方式function关键字(命名函数)
  2. 函数表达式(匿名函数)
  3. new Function(‘参数1’,’参数2’,’函数体’)

                Function里面的参数都必须是字符串格式

                执行效率低,也不方便书写,因此较少使用

                所有函数都是Function的实例(对象)

                函数也属于对象


2.函数的调用和this指向

普通函数   函数名()   函数名.call()    this指向 window

对象的方法   对象名.函数名() this指向对象

构造函数   new 构造函数名() this指向实例对象   原型对象的方法this也指向实例对象

绑定事件函数   触发事件 this指向绑定事件对象即调用者

定时器函数     时间到了自动调用    this指向window

立即调用函数   自动调用 this指向window


3.改变函数内部this指向

call(thisArg,args1,args2)方法

call()  调用这个函数,并且修改函数运行时的this指向

thisArg:当前调用函数this的指向对象

arg1,arg2:传递的其他参数

调用一个函数,调用函数的方式,但是它可以改变函数的this指向

作用:实现继承

function fn(){
    console.log("你好");
};
var o={
    name:"andy"
};
fn.call(o);//此时这个fn()函数里面的this指向了o这个对象

apply(thisArg,argsArray)方法

调用一个函数,调用函数的方式,但是它可以改变函数的this指向

thisArg:当前调用函数this的指向对象

argsArray:传递的值,必须包含在数组里面(伪数组)

返回值就是函数的返回值,因为它就是调用函数

求数组的最大值:Math.max.apply(Math,arr)

bind(thisArg,args1,args2)方法

不会调用函数,但是能改变函数的内部的this指向

thisArg:当前调用函数this的指向对象

arg1,arg2:传递的其他参数

返回由指定的this值和初始化参数改造的原函数拷贝

想要调用函数,可是声明一个变量接收bind()的返回值,之后用变量()即可调用

如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向,此时用bind

<body>
    <button>点击</button>
    <button>点击</button>
    <button>点击</button>
    <script>
        var btns=document.querySelectors('button');
        for(var i=0;i<btns.length;i++){
            btns[i].onclick=function(){
                this.disabled=true;
                setTimeout(function(){
                    // btns[i].disabled=false; 
                     //会报错  因为先执行完for循环
                     //再执行定时器的函数,此时i=4
                    this.disabled=false;
                }.bind(this),3000)  //这个this指向btns[i]
            }
        }
    </script>
</body>

4.call apply bind的比较

相同点:

        都可以改变函数内部的this指向

不同点:

  1. call和apply会调用函数,并且改变函数内部的this指向
  2. call和apply传递的参数不一样,call传递参数arg1,arg2形式,apply必须数组形式[arg]
  3. bind不会调用函数,可以改变函数内部的this指向

主要应用场景

  1. call经常做继承
  2. apply经常跟数组有关系,比如借助数学对象实现数组的最大值,最小值
  3. bind不调用函数,但是还想改变this指向,比如改变定时器内部的this指向

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值