索引

1. 对象与类

支持面向对象编程语言通常利用继承其他类达到代码重用和可扩展性的特性。而类有两个主要的概念:

  • (Class):定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。
  • 对象:是类的实例。

其中(Class)定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。举例来说,“”这个类会包含狗的一切基础特征,即所有“狗”都共有的特征或行为,例如它的品种、毛皮颜色和吠叫的能力。类可以为程序提供模版和结构。一个类的方法和属性被称为“成员

​ 需求:通过手机打电话,分析出里面的对象,有什么特征和行为,对象是什么类型的,此时这些的分析结果,--->抽取出对象的特征和行为

特征--->属性

行为--->方法

对象的类型--->类别

2.对象使用

2.1 语法

  1. 对象.属性名字
  2. 对象['属性名字']
  3. 什么时候使用 对象[属性名字] 的写法
    • 不确定属性名字是什么(属性名字是变量)
    • 属性名字不太规范的时候

2.2 属性

枚举属性

  • for...in

    • 该方法依次访问一个对象及其原型链中所有可枚举的属性。

    • var obj = {a:1, b:2, c:3};
      
      for (var prop in obj) {
        console.log("obj." + prop + " = " + obj[prop]);
      }
      
      // 打印:
      // "obj.a = 1"
      // "obj.b = 2"
      // "obj.c = 3"
      
  • Object.keys(对象)

    • 该方法返回对象 o 自身包含(不包括原型中)的所有可枚举属性的名称的数组。

    • // 简单数组
      var arr = ['a', 'b', 'c'];
      console.log(Object.keys(arr)); // console: ['0', '1', '2']
      
      // 类数组对象
      var obj = { 0: 'a', 1: 'b', 2: 'c' };
      console.log(Object.keys(obj)); // console: ['0', '1', '2']
      
      // 类似数组的对象,随机键排序
      var likeObj = { 100: 'a', 2: 'b', 7: 'c' };
      console.log(Object.keys(likeObj)); // console: ['2', '7', '100']
      
  • Object.getOwnPropertyNames(对象)

    • 该方法返回对象 o 自身包含(不包括原型中)的所有属性(无论是否可枚举)的名称的数组。

3.对象特性


  • 抽象性

  • 拓展性

  • 继承(实现多态)

  • 多态(同一个行为,针对不同的对象产生不同的结果)

    • JavaScript自然有多态,我们看看多态的概念:

      多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

      多态最常见的2种实现方式:

      1. 覆盖
      2. 重载

      覆盖指子类重新定义父类方法,这正好就是基于prototype继承的玩法,这不就是多态么?
      重载是指多个同名但参数不同的方法,这个JavaScript确实没有。

4.对象的创建

4.1 字面量

var obj = {}

4.2 工厂函数

function factoryFn(name,age){
 var obj = new Object()
 obj.name = name
 obj.age = age
 return obj
}
//工厂函数批量创建对象,占内存
obj1 = factoryFn("jack",2)
obj2 = factoryFn("Mery",22)

4.3 构造函数

function structorFn(count, password) {
		this.count = count;
		this.password = password;
		this.validate = function() {
			console.log('我是验证');
		};
	};
let obj3 = new structorFn('admin-mater', '123456');
let obj4 = new structorFn('admin-dev', '123456');

4.4 class类

通过 = 赋值的函数在实例上

通过方法是定义在原型上的

class Student {
		//构造器中的属性最终都是在实例对象上
		constructor(name, age, gender) {
			this.name = name;
			this.age = age;
			this.gender = gender;
		}

		//在构造函数原型上,不能使用this
		sayHi(name, age, gender) {
			console.dir(`我是${name},今年${age}岁了,是${gender}`);
		}

		//在stu实例上
		eat = function() {
			console.log(`${this.name}`);
		};
		//在stu实例上
		play = () => {
			console.log('模拟人生');
		};
	}

	let stu = new Student('红红', '24', 'girl');
	stu.__proto__.sayHi('江江', '23', 'boy');
	stu.eat();

一次搞懂JavaScript对象_构造函数

原型的函数上要传参使用,如果在定义的时候内部是this指向,就会undefined

ex:

一次搞懂JavaScript对象_单例模式_02

4.5 对象与单例模式!!!

创建单例模式对象

一次搞懂JavaScript对象_多态_03

关键词:

  • 对象

  • 垃圾回收

  • 闭包

function createObj() {
		let judge = null;
		return function(name) {
			if (!judge) {
				judge = new Object();
				judge.name = name;
			}
			return judge;
		}
	}
	console.log(typeof null);//object
	let getObj = createObj();//返回访问入口,首次传入的值,会影响之后的所有结果
	//访问入口是函数,函数是对象,所以在这里存储了一个地址0x0000  (getObj)
	let obj5 = getObj('小绿');//调用时,开辟一个新的judge对象地址  0x0001
	//首次调用已经return judge,并且不会被回收!
	let obj6 = getObj('辉sir');//传递了第一次的obj5地址0x0001
	let obj7 = getObj('辉sir');//传递了第一次的obj5地址0x0001
	console.log(obj5);//{name: "小绿"}
	console.log(obj6);//{name: "小绿"}
	console.log(obj7);//{name: "小绿"}
	console.log(obj5 === obj6);//true 引用地址相同,正常情况下Object的打印是false



//抽离核心代码,重新进行函数调用发现并不是唯一入口?
function foo(name) {
	let judge = null;
	if (!judge) {
		judge = new Object();
		judge.name = name;
	}
	return judge;
};

console.log(foo('只') === foo('狼'));//false
//原因是没有形成闭包,返回值被回收了