有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

js 面向对象

javascript cat 10个月前 (12-03) 37次浏览 已收录 0个评论 扫描二维码

1、编程思想

1、面向过程:面向过程思想强调的是步骤,当碰见问题时,思考的是“我该怎么做”,分析出解决问题所需的步骤,一步步的去实现。

2、面向对象面向对象思想强调的是对象,当碰见问题时,思考的是“我该让谁来做”。这个“谁”其实就是对象。找合适的对象做合适的事情。而对象如何去做(采用什么样的步骤)我们就不关心了,最终把问题解决掉就可以了。

面向过程是动作的执行者,面向对象是动作的指挥者

可以理解为:面向对象,你就是老板,安排小弟做事,你在办公室和秘书感叹人生,面向过程:指的就是小弟在给你赚钱~

相关概念:

var 对象 = {
    key1: value1,
    key2: value2,
    ...
}

1、对象:无序的名值对

2、对象组成

1、属性:对象的特征描述,静态,名词(不是函数的就是属性)

2、方法:对象的行为,动态(函数就是方法)

3、对象的基本特征:封装、继承、多态(了解)

4、类和实例

类:类是对象的类型模板

实例:实例是根据类创建的对象

面向对象学习,就是学习创建类(模板),利用类生成实例(月饼)

2、对象的读写

var obj = {
    name: 'zs',
    age: 3,
    a: undefined,
    b: null,
    fn: function () {
        console.log(this);
        console.log('前端开发');
    }
}

// 读
console.log(obj.name); // zs
console.log(obj['name']); // zs
var n = 'name';
console.log(obj[n]); // zs
obj.fn(); // 函数调用,函数中的this是前面的这个对象

// 写
obj.name = '良哥';
obj['age'] = 18;
obj.sex = '男';
console.log(obj);

// -----------------------------
// 循环: for-in
for (var attr in obj) {
    console.log(attr, '-----', obj[attr]);
}

// -----------------------------
// in操作符,检测对象是否有这个属性,有就返回true,否则返回false。不关心它的值
console.log('name' in obj); // true
console.log('a' in obj); // true
console.log('b' in obj); // true

// -----------------------------
// delete : 删除对象的某个属性
delete obj.name;
console.log(obj);

3、面向对象创建

1、字面量创建

// 字面量创建
var person1 = {
    name: 'zs',
    age: 3,
    fn: function () {
        console.log('前端攻城狮');
    }
}

var person2 = {
    name: 'ls',
    age: 5,
    fn: function () {
        console.log('后端抠脚码农');
    }
}

// 不足:这种创建方式,适用于单个对象的创建,如果要创建多个对象,会代码冗余。

2、实例创建

// 实例创建对象,使用 new Object()创建出一个实例对象,然后再给这个对象添加属性和方法。

var person1 = new Object(); // {}
person1.name = '小芳'; // 给对象赋值
person1.age = 18;
person1.fn = function () {
    console.log('貌美如花');
}
console.log(person1);

var person2 = new Object();
person2.name = '小黄';
person2.age = 1;
person2.fn = function () {
    console.log('打猎');
}
console.log(person2);

// 不足:要创建多个对象,会产生代码冗余

3、工厂模式

// 工厂模式创建对象,其实就是函数封装

function person(name, age) {
    // 1、原料
    var obj = new Object();

    // 2、生产
    obj.name = name;
    obj.age = age;
    obj.fn = function () {
        console.log('前端开发');
    }

    // 3、出厂
    return obj;
}

var p1 = person('zs', 3);
console.log(p1);

var p2 = person('ls', 5);
console.log(p2);

// 优点:适合批量创建
// 不足:识别问题,因为根本无法搞清楚他们到底是哪个对象的实例。

instanceof

// instanceof 运算符,一个对象是否为指定的构造函数的实例,返回布尔值
console.log(p1 instanceof person); // false
console.log(p1 instanceof Object); // true  Object在js中,相当于人类的地球

var arr = [];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true

4、构造函数模式

构造函数的特点:

1、构造函数名首字母大写(为了区分普通函数,不是必须,是约定)

2、构造函数方法没有显示的创建对象(new Object())

3、直接将属性和方法赋值给 this 对象

4、没有 return 语句,不需要返回对象

5、通过构造函数创建对象,必须使用 new 运算符(直接调用跟普通函数一样)

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.fn = function () {
        console.log('前端开发');
    }
}

构造函数的执行过程:

(1) 立刻创建一个新的对象、

(2) 将新的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象、

(3) 逐行执行函数中的代码

(4) 将新建的对象作为返回值返回

var p1 = new Person('zs', 3);
console.log(p1);

var p2 = new Person('ls', 5);
console.log(p2);

// 优点:解决了识别问题
console.log(p1 instanceof Person); // true
console.log(p1 instanceof Object); // true

// 不足:一模一样的函数,在内存中会创建多次,存在浪费内存空间的问题
console.log(p1.fn)
console.log(p2.fn)
// 为什么不相等,因为new Person()每调用一次,创建的函数的地址不同,因此不相等
console.log(p1.fn == p2.fn); // false 

// -------------------------------
// 如果不通过new调用构造函数,哪会怎么样?
// 属性和方法都加到了全局的window上,且没有return,即调用的结果为undefined
// var p = Person('zs', 3);
// console.log(p);

对象的比较

// 基本类型的比较:是值的比较
console.log(5 == 5); // true

// 引用类型的比较:是地址的比较
console.log([] == []); // false
console.log({} == {}); // false
console.log(function () { } == function () { }); // false

5、原型创建对象

1、原型:js每声明一个function,都有prototype原型,prototype原型是函数的一个默认属性,在函数的创建过程中由js编译器自动添加。也就是说:当生产一个function对象的时候,就有一个原型prototype。原型中存储对象共享的属性和方法。

2、原型链:当查找对象的属性的时候,先找自身,如果自身没有,则找顺着__proto__找到原型,如果原型也没有,则继续向上找,一直找到Object的原型。这个查找这个链表就是原型链。

var arr = new Array(); // arr即实例  Array即构造函数
arr.push(1);

console.log(arr);
console.log(arr.__proto__); // 通过实例 访问数组的原型对象
console.log(Array.prototype); // 通过构造函数 访问数组的原型对象
console.log(arr.__proto__ == Array.prototype); // true

console.log(Array.prototype.constructor); // 原型下面有一个constructor的属性,又指向构造函数

// -----------------------
function fn() { }

// 每创建一个函数,它默认都会有原型对象
console.log(fn.prototype); // {constructor: ƒ}
// 原型下面默认有一个constructor的属性,又指向函数
console.log(fn.prototype.constructor); // fn

js 面向对象

原型创建对象

function Person() { }

// console.log(Person.prototype); // 只要创建一个函数,它就会有原型对象  {constructor: f}

Person.prototype.name = 'zs';
Person.prototype.age = 3;
Person.prototype.fn = function () {
    console.log('前端开发');
}

var p1 = new Person();
console.log(p1);
console.log(p1.name); // zs  为什么能访问到原型上的name,因为原型上的属性和方法对所有的实例共享
p1.fn();
console.log(p1.toString);
console.log(p1.abc);

// 原型链:对象查找属性的过程,先找自身,如果自身找到了,则返回这个属性,如果自身没有,
则顺着原型链找到上一级原型,如果上一级原型还是没有,则继续向上找,一直找到Object的原型,
如果Object的原型也没有,则报undefined。

var p2 = new Person();
console.log(p2.name); // zs

// --------------------------------
// 原型创建对象解决了构造函数重复创建同一个函数的问题
// 不足:不能传参,创建的对象一样

js 面向对象

6、混合模式创建对象(标准方法)

// 构造函数和原型的混合(创建对象的标准方法)
// 属性写在构造函数中,方法写在原型上
function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.showName = function () {
    console.log(this.name);
}
Person.prototype.showAge = function () {
    console.log(this.age);
}

var p1 = new Person('zs', 3);
console.log(p1);
console.log(p1.name); // zs
p1.showName();

var p2 = new Person('ls', 5);
console.log(p2);

js 面向对象

7、动态混合模式

function Person(name, age) {
    this.name = name;
    this.age = age;

    if (!Person.prototype.showName) {
        Person.prototype.showName = function () {
            console.log(this.name);
        }
        Person.prototype.showAge = function () {
            console.log(this.age);
        }
    }
}

var p1 = new Person('zs', 3);
console.log(p1);

var p2 = new Person('ls', 5);
console.log(p2);
喜欢 (0)
cat
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址