js学习之面向对象

拟墨画扇 提交于 2019-11-27 06:10:17

一、创建对象的方法


1、 {} 字面量创建

        var person ={
            name: "lisi",
            age: 21,
            say: function(){
                alert(this.name);
            }
        };

 


2、 new Object()

var person = new Object();
person.name = "lisi";
person.age = 21;
person.family = ["lida","lier","wangwu"];
person.say = function(){
       alert(this.name);
}

 

3: 用构造函数创建

function Person(name,age,family) {
    this.name = name;
    this.age = age;
    this.family = family;
    this.say = function(){
        alert(this.name);
    }
}
var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
var person2 = new Person("lisi",21,["lida","lier","lisi"]);
console.log(person1 instanceof Object); //true
console.log(person1 instanceof Person); //true
console.log(person2 instanceof Object); //true
console.log(person2 instanceof Person); //trueconsole.log(person1.constructor);      //constructor 属性返回对创建此对象的数组、函数的引用

 


4:Object.create方法创建
创建完的对象有2个特点
1、 可以添加属性 (属性的值为非函数的任意数据类型)
2、 添加方法

const person = {
    isHuman: false,
    say: function () {
        console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
    }
};

const me = Object.create(person); //使用现有的对象来提供新创建的对象的__proto__

 

5、工厂模式

function createPerson(name,age,family) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.family = family;
    o.say = function(){
        alert(this.name);
    }
    return o;
}

var person1 =  createPerson("lisi",21,["lida","lier","wangwu"]);   //instanceof无法判断它是谁的实例,只能判断他是对象,构造函数都可以判断出
var person2 =  createPerson("wangwu",18,["lida","lier","lisi"]);console.log(person1 instanceof Object); //true

 

6、原型模式

function Person() {}

Person.prototype.name = "lisi";
Person.prototype.age = 21;
Person.prototype.family = ["lida","lier","wangwu"];
Person.prototype.say = function(){
    alert(this.name);
};
console.log(Person.prototype);   //Object{name: 'lisi', age: 21, family: Array[3]}

var person1 = new Person();        //创建一个实例person1
console.log(person1.name);        //lisi

var person2 = new Person();        //创建实例person2
person2.name = "wangwu";
person2.family = ["lida","lier","lisi"];P9
console.log(person2);            //Person {name: "wangwu", family: Array[3]}
// console.log(person2.prototype.name);         //报错
console.log(person2.age);              //21

 

7、混合模式(构造函数模式+原型模式)

构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性
function Person(name,age,family){
    this.name = name;
    this.age = age;
    this.family = family;
}

Person.prototype = {
    constructor: Person,  //每个函数都有prototype属性,指向该函数原型对象,原型对象都有constructor属性,这是一个指向prototype属性所在函数的指针
    say: function(){
        alert(this.name);
    }
}

var person1 = new Person("lisi",21,["lida","lier","wangwu"]);
console.log(person1);
var person2 = new Person("wangwu",21,["lida","lier","lisi"]);
console.log(person2);

 


new的工作原理


  通过new创建对象经历4个步骤

  1、创建一个新对象;[var o = {};] //创建一个空对象obj,然后把这个空对象的__proto__设置为Person.prototype(即构造函数的prototype);

  2、将构造函数的作用域赋给新对象 (因此this指向了这个新对象);[Person.apply(o)] [Person原来的this指向的是window]

  3、执行构造函数中的代码(为这个新对象添加属性);

  4、返回新对象。

 

什么是面向对象编程(OOP)?

面向过程与面向对象
  1)面向过程:面向过程专注于如何去解决一个问题的过程步骤。编程特点是由一个个函数去实现每一步的过程步骤,没有类和对象的概念。
  2)面向对象:专注于由哪一个对象来解决这个问题,编程特点是出现了一个类,从类中拿到对象,由这个对象去解决具体问题。 对于调用者来说,面向过程需要调用者自己去实现各种函数。而面向对象,只需要告诉调用者,对象中具体方法的功能,而不需要调用者了解方法中的实现细节。

面向对象的三大特征
面向对象的三大特征是继承封装多态。JS可以模拟实现继承和封装,但是无法模拟实现多态,所以我们说JS是一门基于对象的语言,而非是面向对象的语言。

 

 

类和对象
1、:一类具有相同特征(属性)和行为(方法)的集合。
比如,人类具有身高、体重等属性,吃饭、大笑等行为,所以,我们可以把人划分为一类。


2、对象:从类中,拿出具有确定属性值和方法的个体。
比如,张三-->属性:身高180体重180 方法:说话-->我叫张三,身高180

3、类和对象的关系

①类是抽象的,对象是具体的(类是对象的抽象化,对象是类的具体化)

②类是一个抽象的概念,只能说类有属性和方法,但是不能给属性赋具体的。比如,人类有姓名,但是不能说人类的姓名叫什么。
对象是一个具体的个例,是将类中的属性进行具体赋值而来的个体。
比如,张三是一个人类的个体。可以说张三的姓名叫张三。也就是张三对人类的每一个属性进行了具体的赋值,那么张三就是由人类产生的一个对象。

4、使用类和对象的步骤:
1)创建一个类(构造函数):类名必须使用大驼峰法则。即每个单词首字母都要大写

function 类名(属性1){
    this.属性1=属性1;
    this.方法=function(){
    //方法中要调用自身属性,必须使用this.属性
    }
}

 


2)通过类实例化(new)出一个对象。

var obj=new 类名(属性1的具体值);
obj.属性; 调用属性
obj.方法; 调用方法

 


3)注意事项:
①通过类名,new出一个对象的过程,叫做"类的实例化"。
②类中的this,会在实例化的时候,指向新new出的对象。
所以,this.属性 this.方法实际上是将属性和方法绑定在即将new出的对象上面。
③在类中,要调用自身属性,必须使用this.属性名。如果直接使用变量名,则无法访问对应的属性。

function Person(name,age){
    this.name=name;
    this.age=age;
    this.say=function(content){
        //在类中,访问类自身的属性,必须使用this.属性调用。
        alert("我叫"+this.name+",今年"+this.age+"岁,我说了一句话:"+content);
    }
}
var zhangsan=new Person("姐姐",18);
zhangsan.say("你好呀");

 

类名必须使用大驼峰法则,注意与普通函数区分。

面向对象的两个重要属性

1)constructor:返回当前对象的构造函数。

2)instanceof:检测一个对象是不是一个类的实例;

>>>lisi instanceof Person          //true √ lisi是通过Person类new出的
>>>lisi instanceof Object          //true √ 所有对象都是Object的实例
>>>Person instanceof Object        //true √ 函数本身也是对象

 


成员属性、静态属性和私有属性
1、在构造函数中,使用this.属性声明。或者在实例化出对象以后,使用"对象.属性"追加的,都属于"成员属性或成员方法"。也叫"实例属性或实例方法"。
成员属性/方法,是属于由类new出的对象的。
需要使用"对象名.属性名"调用。

【静态属性与静态方法】
2、通过“类名.属性名”、“类名.方法名”声明的属性和方法,称为静态属性、静态方法。也叫类属性和类方法。
类属性/类方法,是属于类的(属于构造函数的)
通过"类名.属性名"调用。

3、成员属性是属于实例化出的对象的,只能使用对象调用。
静态属性是属于构造函数的,只能使用类名调用。

[私有属性和私有方法]
4、在构造函数中,使用var声明的变量称为私有属性;
在构造函数中,使用function声明的函数,称为私有方法;

function Person(){
    var num=1;//私有属性
    function func(){}//私有方法
}

 


私有属性和私有方法的作用域,只在构造函数内容有效。即只能在构造函数内部使用,在构造函数外部,无论使用对象名还是类名都无法调用。

 

 

JavaScript中的this指向详解

1、谁最终调用函数,this最终指向谁(记住!)
①this指向谁,不应考虑函数在哪声明,而应该考虑函数在哪调用!!!
②this指向的永远只可能是对象,而不可能是函数。
③this指向的对象,叫做函数的上下文context,也叫函数的调用者。


2、this指向的规律!!!(跟函数的调用方式息息相关,记住这点,相信你一定会分清this指向哒)
①通过函数名()调用的,this永远指向window
②通过对象.方法调用的,this指向这个对象。
③函数作为数组中的一个元素,用数组下标调用的,this指向这个数组
④函数作为window内置函数的回调函数使用,this指向window。 setInterval setTimeout 等。
⑤函数作为构造函数,使用new关键字调用,this指向新new出的对象。

var fullname = 'John Doe';
var obj = {
    fullname: 'Colin Ihrig',
    prop: {
        fullname: 'Aurelio De Rosa',
        getFullname: function () {
            return this.fullname;
        }
    }
};

console.log(obj.prop.getFullname()); //Aurelio De Rosa
// 函数的最终调用者 obj.prop 

var test = obj.prop.getFullname;
console.log(test()); //John Doe
// 函数的最终调用者 test()  this-> window

obj.func = obj.prop.getFullname;
console.log(obj.func()); //Colin Ihrig
// 函数最终调用者是obj

var arr = [obj.prop.getFullname, 1, 2];
arr.fullname = "JiangHao";  //JiangHao
console.log(arr[0]()); // 函数最终调用者数组

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!