JavaScript知识点总结6

 

一.面向对象:在程序中都是用一个对象来描述现实中一个具体的东西。

1.现实中的一个东西都包含属性和功能:

(1)属性:描述一个东西特点的变量,一个值;

(2)功能:东西可以执行的操作。

2.对象:封装多个数据和方法的存储空间。

3.自定义对象:封装现实中一个东西的属性和功能的存储空间。

      现实中东西的属性,会成为对象中的属性变量;

      现实中东西的功能,会成为对象中的方法(函数)。

4.面向对象三大特点:封装、继承、多态

(1)封装:将描述同一类东西的属性和方法,定义在一个对象中;

(2)继承:父对象中的属性和方法,子对象可直接使用;

(3)多态:同一个对象,在不同情况下,呈现不同的状态。

         *重载:同一方法名,传入参数不同,执行不同的操作;

         *重写:子对象觉得父对象的成员不好用,可自己定义一个,覆盖父对象的成员。

二.创建自定义对象(4种):(封装)

1.直接变量

var hmm={
    sname:"Han MM",
    age:11,
    intrSelf:function(){
        alert("I`m Han MM,I`m 11")
    }
}

Js中一切都是对象!所有对象的底层都是hash数组。(遍历对象的所有成员,相当于遍历hash数组中每个元素)

属性:如何访问属性:(2种):obj.属性名; obj["属性名"]

(1)访问对象中不存在的属性(访问数组中不存在的下标),不会出错,返回undefined

(2)强行给不存在的属性赋值,不报错,js自动创建同名属性。

如何判断某个对象是否包含指定成员:(3种)

(1)obj.hasOwnProperty("成员名");  找到true;没有false。

(2)"属性名" in 对象;  找到true;没有false。

(3)直接使用 obj.属性名;作为条件:

          arr.indexOf===undefined

          若不包含,返回undefined —> false

          若包含,返回值或function —> true

          何时省略:判断方法是否存在时,可省略===;如果确定属性值不是null、0、" "、NaN 时也可省略。

如何在方法中,访问当前对象自己:this关键字

***this关键字:运行时,指代正在*调用*方法的对象(即 . 前的对象)。

***this本质是window下唯一的指针,指向当前正在调用方法的对象。(this只有一个

***在方法内访问当前对象自己的属性,必须用this.属性名。

***this和定义在哪无关!仅和调用时使用的当前对象有关。

***如果无主的调用或赋值,默认this都是window!

/*笔试题*/
//this-->window, 刚开始什么都没有时
var a = 2;
//this-->window
function fun(){
    console.log(this.a);
}
//this-->window
var o = {a:3, fun:fun}; //this-->o, 因为定义的是对象
var p = {a:4}; //this-->p
o.fun(); //this-->o

(p.fun = o.fun)();  //2
//o.fun中存放的是函数fun的地址0x1011.
//p.fun=0x1011;  p={a:4, fun:0x1011};  即返回o.fun中的值!0x1011
//***赋值表达式的结果相当于等号右侧表达式的值!!!
//则,(0x1011)();--->即匿名函数自调-->this-->window
p.fun;  //this-->p;输出4

2.var obj = new Object();//创建一个空对象

   obj.属性名 = 值;

   obj.方法名 = function(){...this.属性名...}

3.利用构造函数*反复*创建*相同结构*的对象:(2步)

   构造函数:描述一类对象结构的特殊函数。

(1)定义构造函数

(2)利用构造函数创建对象

          new:1.创建一个空对象:new obj={  };

                     2.用空对象,调用构造函数;构造函数在空对象中添加属性和方法;

                     3.设置新对象的_proto_,指向构造函数的prototype对象;(程序自动设置_proto_)

所有对象都有_proto_属性,且指向其构造函数的prototype对象。(_proto_指向其父级对象)

                     4.返回新对象的地址。

/*先定义构造函数*/
function Student(sname, age){
    this.sname = sname;
    this.age = age;
    this.intrSelf = function(){
        alert("I`m"+ this.sname + "I`m"+ this.age);
    };
}

/*利用构造函数创建对象*/
var lilei = new Student("Li Lei",12);

 

function Student(sname, age){
    this.sname=sname;
    this.age=age;
}
//在构造函数原型对象中定义公共方法
Student.prototype.intrSelf=function(){
    alert("I`m"+ this.sname + "I`m"+ this.age);
}

var lilei=new Student("Li Lei",12);
var hmm=new Student("Han MM",11);

Student.prototype.money=100;
console.log(lilei.money);  //输出100。 先在当前对象本地找; 找不到再去原型找; 原型也没有才undefined。

4.Object.create(父对象,{扩展属性的列表对象})

三.继承:js中一切继承都是用原型对象实现的!

原型对象:每个函数对象都有一个原型对象。

构造函数的原型对象负责保存所有子对象共享的成员!(构造函数的原型对象负责保存所有,利用构造函数创建的所有子对象,共享的成员。即,如果子对象有相同的部分,都放在构造函数的原型中,取缔构造函数中的。)

建议:所有子对象共享的方法,都应定义在构造函数的原型中。----避免重复定义方法对象,浪费内存。

所有内置对象的方法都是定义在构造函数对象的原型中的(也应该是这样,节省内存),比如:Array.prototype.xxx;(xxx是Array中的方法)属性是定义在构造函数中的。

子对象不能够修改原型中的共享属性,只读。  

所有对象都有什么属性、方法,取决于Object.prototype中定义了哪些属性、方法。(原型prototype存放共同成员

(1)扩展对象属性:2种扩展

1.扩展共有属性:通过构造函数.prototype添加的属性;

2.扩展自有属性:通过某一个具体子对象添加的属性;

(2)判断自有属性或共有属性:

1.判断自有属性:obj.hasOwnProperty("属性名");

2.判断共有属性:"属性名" in obj   &&  !obj.hasOwnProperty("属性名");

                             原型关系中包含      &&      子对象没有

3.判断原型链上的属性:(判断不包含)

(1)if(!("属性名" in obj))

(2)if(obj.属性名===undefined)

(3)if(!obj.属性名)

(3)删除属性:delete 对象.属性名;     仅能删除当前对象自己的属性,无法删除共有属性。

(4)原型、原型链、继承:

1.原型:保存所有子对象共有属性和方法的对象!

***所有函数都有prototype,指向自己的原型对象;

***所有对象都有_proto_,指向自己父级原型对象。

***所有原型对象都有constructor,指回原型对应的构造函数。

2.原型链:所有父子级对象间由_proto_形成的多级引用关系 ——> 多级继承

3.原型相关API:

(1)判断自有属性或共有属性:见上

(2)获得任意对象原型:obj._proto_;  Object.getPrototypeOf(obj);

(3)判断父对象是否在子对象的原型链上:父对象.isPrototypeOf(子对象);

(5)***检测一个对象是不是数组类型:(4种)

在 JS 里使用 typeof 来判断数据类型,只能区分基本类型,即 “number,string,undefined,boolean,object,function”,symbol” (ES6新增)七种。对于数组、null、对象来说,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。

1.Array.prototype.isPrototypeOf(obj);

2.obj instanceof Array;(对象 是不是 构造函数 的实例)

3.obj.constructor==Array;仅判断直接父级

4.利用当前对象,强行调用原始的toString方法:(不同的原型对象的toString方法有不同的作用)

        Object.prototype.toString.call(obj)=="[object  Array]";

        Object.prototype.toString.apply(obj)=="[object  Array]";

js中的对象都继承自Object,所以当我们在某个对象上调用一个方法时,会先在该对象上进行查找,如果没找到则会进入对象的原型(也就是.prototype)进行查找,如果没找到,同样的也会进入对象原型的原型进行查找,直到找到或者进入原型链的顶端Object.prototype才会停止。

所以,当我们使用arr.toString()时,不能进行复杂数据类型的判断,因为它调用的是Array.prototype.toString,虽然Array也继承自Object,但js在Array.prototype上重写了toString,而我们通过toString.call(arr)实际上是通过原型链调用了Object.prototype.toString。(详见:https://www.cnblogs.com/bq-med/p/8796836.html

call方法: 调用一个对象(Object)的一个方法,以另一个对象(obj)替换当前对象。(改变this指向)apply与其一样

详见:https://www.cnblogs.com/sghy/p/7646633.htmlhttps://uule.iteye.com/blog/1158829

继承:代码重用!节省空间!

1.直接继承对象:想方设法修改对象的_proto_

(1)仅修改一个对象的_proto_:

            Object.setPrototypeOf(子对象,父对象);用于给子对象一个新的原型父对象。(给子对象新找了个干爹)

(2)通过修改构造函数的原型对象,实现批量修改后续子对象的继承关系:

            构造函数.prototype=父对象;(改变构造函数)

            强调:仅影响之后创建的对象的继承关系,之前创建的对象依然继承,旧构造函数.prototype

(3)var obj=Object.create(父对象 [,{属性列表}])

            创建一个空对象;继承父对象中的属性;继承同时可再扩展属性和方法。

2.仅继承结构:模拟Java中的继承

/*定义一个构造函数包含所有飞行物的属性---父*/
function Flyer(fname, speed){
    this.fname=fname;
    this.speed=speed;
    this.fly=function(){
        console.log(this.fname+"以时速:"+this.speed+"飞行");
    };
}

/*再定义一个飞机构造函数,除包含飞行物的所有属性外,还扩展容量属性---子*/
function Plane(fname, speed, capacity){
    //先调用Flyer构造函数
    //用当前正在创建的对象强行调用window.Flyer
    //并传入所需参数
    Flyer.call(this,fname,speed);
    //Flyer.apply(this,[fname,speed]);
    this.capacity=capacity;
}

var A380=new Plane("A380",1800,555);
//_proto_ ---> Plane.prootype
//1.创建空对象
//2.调用Plane():先调用Flyer构造函数,再添加capacity属性。
A380.fly();

 只要见到“[ ]”,就是数组;只要见到“{ }”,就是对象。

任何一个方法使用变量,只会从自己的活动范对象中,或window全局下找变量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值