javascript 对象、原型、原型链、类

1.1 JavaScript 对象

  • 所有事物都是对象:字符串、数值、数组、函数…
  • 对象为一组属性或方法的无序集合
  • 对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值

1.2 创建 JavaScript 对象

  • 创建直接的实例
	person=new Object();
	person.name="xxh";
	person.age=24;
	person.job="student";
  • 使用对象字面量
	let person = {
		name: "xxh";
		age: 24;
		job: "student";
	}
  • 使用构造函数(函数声明、函数表达式)
	function Person(name,age,job){
		this.name = name;
		this.age = age;
		this.job = job;
	}
	let Person = function(firstname,lastname,age,eyecolor){
		this.name = name;
		this.age = age;
		this.job = job;
	}

注:按照惯例,构造函数的首字母都要大写。

1.3 原型

原型可以理解成模板,用来模仿JAVA中的类。

先看下面两个例子:

	function Person(name,age,job){
		this.name = name;
		this.age = age;
		this.job = job;
		this.sayName = function(){
			console.log(this.name);
		};
	}
	
	let person1 = new Person("xxh",24,"student");
	let person2 = new Person("whh",24,"student");
	
	console.log(person1.sayName() == person2.sayName());//false
		var arr1 = [1, 0, 0, 8, 6];
		var arr2 = [1, 0, 0, 8, 6, 1, 1];
	    
	    //数组求和方法
		arr1.getSum = function() {
			var sum = 0;
			for(var i = 0; i < this.length; i++) {
				sum += this[i];
			}
			return sum;
		}
		console.log(arr1.getSum()); //输出15
		console.log(arr2.getSum());//控制台报错

第一个例子中,虽然实例上的函数同名且作用相同,但却是不同的对象。

第二个例子中,在 arr1 上定义的方法,只属于arr1,不属于arr2,因此如果arr2要求和的话还得在arr2上重新定义求和方法。

问题:有没有什么方法可以只做一件事就能解决相同逻辑的需求?

这个问题可以通过原型来解决。

1.3.1 原型

每个JavaScript对象创建的时候,都会创建一个prototype属性,这个prototype就是我们说的原型,它是一个对象。

这个对象作用类似于JAVA中的类,里面储存可以共享的属性和方法。

	let Person = function(){};
	Person.prototype.name = "xxh";
	Person.prototype.age = 24;
	Person.prototype.job = "student";
	
	let person1 = new Person();
	let person2 = new Person();
	
	console.log(person1.sayName() == person2.sayName());//true

通过原型定义的属性和方法是由所有实例共享的,因此person1和person2访问的是相同的sayName( )。

1.3.2 原型搜索机制

原型链是原型定义方式的属性查找机制。

在通过对象访问属性时,会按照这个属性的名称开始搜索。搜索开始于对象实例本身。如果在这个实例上发现了给定的名称,则返回该名称对应的值。如果没有找到这个属性,则搜索沿着指针进入原型对象,然后在原型对象上找到属性后,再返回对应的值。

在这里插入图片描述
上图为原型图解,对于实例person1而言,当需要访问sayName时,会首先搜索person1实例本身,没有发现则进入prototype对象搜索,得到sayName方法。

1.4 类

在ES6中为了解决原型实现继承的代码过于冗长的问题,正式定义了类。

1.4.1 类定义

  • 以表达式定义类
        //匿名类
        let Example = class {
            constructor(a) {
                this.a = a;
            }
        }
        //命名类
        let Example = class Example {
            constructor(a) {
                this.a = a;
            }
        }
  • 以声明方式定义类
        class Example {
            constructor(a) {
                this.a = a;
            }
        }

1.4.2 类方法

  • 类构造函数

    constructor方法是类的默认方法,创建类的实例化对象时自动被调用,不定义时相当于将构造函数定义为空函数。

        class Example {
            constructor() {
                console.log("前端真好玩!");
            }
        }
        new Example();//前端真好玩!

当使用new创建对象时,构造函数会执行以下操作:

	1.在内存中创建对象
	2.给这个对象的 prototype 赋值
	3.构造函数内部的 this 赋值为这个对象
	4.执行构造函数内部的代码(给新对象添加属性)
	5.如果指定了返回对象,则返回该对象;否则返回刚创建的新对象
  • 原型方法

    把在类块中定义的方法定义到原型中,以便在实例间共享。

        class Example {
            sum(a, b) {
                console.log(a + b);
            }
        }
        let exam = new Example();
        exam.sum(1, 2);//3
  • 静态方法

    静态方法通常用于执行不需要实例来完成的操作。静态方法的 this 指向类本身。

        class Example {
            static sum(a, b) {
                console.log(a + b);
            }
        }
        Example.sum(1, 2);//3

1.4.3 继承

通过 extends 实现类的继承。

  • super

    用来新建父类的 this 对象。

    子类没有自己的 this 对象,如果不调用 super,子类就得不到 this 对象。

		class Demo2 extends Demo{
			constructor(x,y){
				 this.x = x;		//this is not defined
			 }
		}

调用父类方法,super 在静态方法中指向父类,在普通方法中指向父类的原型对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值