【前端系列教程之JavaScript】06_JavaScript自定义对象

JavaScript对象

类和对象的概念

为什么要有对象

function printPerson(name, age, sex....) {
}
// 函数的参数如果特别多的话,可以使用对象简化
function printPerson(person) {
  console.log(person.name);
  ……
}

什么是对象

        所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对象,它是一种具体的存在,可以发现身边很多对象,汽车,狗,人等,这些对象都有一个属性和行为。

        比如一只狗,那么它的属性有名称、品种、颜色、体重;行为有吠叫、摇摆、跑等。

JavaScript中的对象

        JavaScript语言没有“类”,而改用构造函数(constructor)作为对象的模板。前面说过,“对象”是单个实物的抽象。所以,通常需要一个模板,表示某一类实物的共同特征,然后“对象”根据这个模板生成。所谓“构造函数”,就是专门用来生成“对象”的函数。它提供模板,作为对象的基本结构。比如var date1=new Date()是通过调用Date的构造函数Date()(这里可以理解为一个类)来创建一个日期对象。一个构造函数,可以生成多个对象,这些对象都有相同的属性和行为,但是属性值可以不同。

        在 JavaScript 中,不会创建类,也不会通过类来创建对象(就像在其他面向对象的语言中那样),JavaScript 基于 prototype(原型),而不是基于类的。

        在Javascript没有类和接口,只有对象,而根据ECMAscript的定义,对象是“无序属性的集合,其属性包含基本值,对象或者函数”。

        需要注意的是,在ECMAscrip6.0中,已经使用class来定义类了。

        对象object是JavaScript的核心概念,也是最重要的数据类型。JavaScript的所有数据都可以被视为对象。对象是一个容器,封装了属性(propert)和方法(method)。所谓属性,就是对象的静态状态;所谓方法,就是对象的动态行为

        JavaScript的对象是无序属性的集合。

        其属性可以包含基本值、对象或函数。对象就是一组没有顺序的值。我们可以把JavaScript中的对象想象成键值对,其中值可以是数据和函数。

        对象的行为和特征

                特征---属性:事物的特征在对象中用属性来表示。

                行为---方法:事物的行为在对象中用方法来表示。

        在JavaScript中,其中一种定义对象的方法如下:

var o = {
    p: "Hello World",
    sayHello:function(){
        return p;
    }
};

        上面代码中,定义了一个对象o,这个对象内部包含2个键值对:p和sayHello,其中p键值对是描述静态属性的;sayHello键值对是描述对象的动态行为的。属性名与属性值之间用冒号分隔。

        p是对象的属性名,字符串“Hello World”是对象的属性值。sayHello是对象的另一个属性名,属性值是function(){return p; }。

        如果对象内部包含多个属性对,每个属性对之间用逗号分隔。 需要注意的是,上面的代码后台隐式调用了new Object()这个构造函数创建了一个对象o,再通过键值对定义静态属性动态行为

对象又分内置对象和自定义对象,其中内置对象是指JavaScript中已经定义好的,比如我们之后学的Date、Array、Math、String等,这些内置对象提供了许多方法和属性,只管调用和使用即可,比如Math对象中的PI和E是属性,pow(x,y)、sin(x)、sqrt(x)等方法。

        而在这一小节里,主要介绍自定义对象的使用。

对象的使用

对象的创建方式

对象字面量

var hero = {
    name: '黄忠',
    weapon: '弓箭',
    equipment: ['头盔', '靴子', '盔甲'],
    blood: 100,
    attack: function () {
        console.log(this.name + ':射箭');
    },
    run: function () {
        console.log(this.name + ': 加速跑');
    }
}
console.log(hero.name);
console.log(hero.equipment);

hero.attack();
hero.run(); 

new Object()创建对象

// Object 是一个构造函数
// new 的方式来调用构造函数
// new Object() 调用构造函数   会在内存中创建一个对象
var hero = new Object(); // 创建了一个空的对象
// 打印一个不存在的属性 输出 undefined
// console.log(hero.name);
// 属性
// JavaScript的动态特性
hero.name = '关羽';
hero.weapon = '青龙偃月刀';
hero.equipment = ['头盔', '靴子', '赤兔马'];
hero.blood = 100;
// 方法
hero.attack = function () {
    console.log(this.name + ': 射箭');
}
hero.run = function () {
    console.log(this.name + ': 加速跑')
}

工厂函数创建对象

function createHero(name, weapon, equipment, blood) {
    var hero = new Object(); //返回一个空的对象
    // 属性
    hero.name = name;
    hero.weapon = weapon;
    hero.equipment = equipment;
    hero.blood = blood;
    // 方法
    hero.attack = function () {
        console.log(this.name + ':攻击');
    }
    hero.run = function () {
        console.log(this.name + ':加速跑');
    }
    return hero;
}

var hero1 = createHero('黄忠', '弓箭', ['头盔', '靴子'], 100);
var hero2 = createHero('刘备', '剑', ['头盔', '盔甲'], 100);

自定义构造函数

function Hero(name, weapon, equipment, blood) {
    // this 动态的给对象增加成员
    // this 指向了当前对象
    this.name = name;
    this.weapon = weapon;
    this.equipment = equipment;
    this.blood = blood;

    this.attack = function () {
        console.log(this.name + ':攻击');
    }
    this.run = function () {
        console.log(this.name + ': 加速跑');
    }
}

var hero1 = new Hero('黄忠', '弓箭', ['头盔', '靴子'], 100);
var hero2 = new Hero('刘备', '剑', ['头盔', '盔甲'], 100);

        this代表的是当前对象

        但是构造函数方有个缺点,就是对象的方法放在了构造函数内部,这样每创建一个方法就会需要多占用一些内存,所以js给构造函数设计了一个prototype属性,用来存放对象的方法:

function Student(name,age,id){
    this.name=name;
    this.age=age;
    this.id=id;
}
Student.prototype={
    work:function(skill){
        alert(this.name+"做"+skill+"开发相关的工作");
    },
    classId:"Java1班"
}
var stu1=new Student("李明",18,20151515);//得到的就是字面量对象
var stu2=new Student("王磊",18,20141000);//得到的就是字面量对象	

console.log(stu2.work==stu1.work);//ture,节省了内存空间
stu1.work("Java");
stu2.work("PHP");
console.log(stu1.classId);//20151515
console.log(stu2.classId);//20141000

属性和方法

        如果一个变量属于一个对象所有,那么该变量就可以称之为该对象的一个属性,属性一般是名词,用来描述事物的特征。 ​

        如果一个函数属于一个对象所有,那么该函数就可以称之为该对象的一个方法,方法是动词,描述事物的行为和功能。

关键字详解

new关键字

构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。

  1. 构造函数用于创建一类对象,首字母要大写。

  2. 构造函数要和new一起使用才有意义。

// Student 自定义构造函数
// 属性:name age sex score
// 方法:sayHi
function Student(name, age, sex, score) {
    // 属性
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.score = score;
    // 方法
    this.sayHi = function () {
        console.log(this.name + ': hello');
    }
}

var stu1 = new Student('lilei', 18, '男', 100);
var stu2 = new Student('hanmeimei', 17, '女', 100);

new在执行时会做四件事情

        new会在内存中创建一个新的空对象
        new 会让this指向这个新的对象
        执行构造函数  目的:给这个新对象加属性和方法
        new会返回这个新对象

this详解

        JavaScript中的this指向问题,有时候会让人难以捉摸,随着学习的深入,我们可以逐渐了解
现在我们需要掌握函数内部的this几个特点
        1. 函数在定义的时候this是不确定的,只有在调用的时候才可以确定
        2. 一般函数直接执行,内部this指向全局window
        3. 函数作为一个对象的方法,被该对象所调用,那么this指向的是该对象
        4. 构造函数中的this其实是一个隐式对象,类似一个初始化的模型,所有方法和属性都挂载到了这个隐式对象身上,后续通过new关键字来调用,从而实现实例化

对象的使用方法

对象属性的使用:

        1、可以用点符号访问对象属性值

        2、也可以通过数组的方式,即用["属性名称"]

对象方法的使用:

        可以使用对象名.方法名()来调用

遍历对象的属性

通过for..in语法可以遍历一个对象

var obj = {
    name: '张三',
    age: 18,
    sex: true,
    sayHi: function () {
        console.log(this.name);
    }
};
for(var key in obj) {
  console.log(key + "==" + obj[key]);
}

删除对象的属性

function fun() { 
  this.name = 'mm';
}
var obj = new fun(); 
console.log(obj.name); // mm 
delete obj.name;
console.log(obj.name); // undefined

简单类型和复杂类型的区别

基本类型又叫做值类型,复杂类型又叫做引用类型

值类型:简单数据类型,基本数据类型,在存储时,变量中存储的是值本身,因此叫做值类型。

Number String Boolean Null Undefined

引用类型:复杂数据类型,在存储是,变量中存储的仅仅是地址(引用),因此叫做引用数据类型。

Object Array

堆和栈

        堆栈空间分配区别:
          1、栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。 
          2、堆(操作系统): 存储复杂类型(对象),一般由程序员分配释放, 若程序员不释放,由垃圾回收机制回收。

        注意:JavaScript中没有堆和栈的概念,此处我们用堆和栈来讲解,目的方便理解和方便以后的学习。

基本类型在内存中的存储:

【前端系列教程之JavaScript】06_JavaScript自定义对象_第1张图片

 复杂类型在内存中的存储:

【前端系列教程之JavaScript】06_JavaScript自定义对象_第2张图片

 基本类型作为函数的参数:

【前端系列教程之JavaScript】06_JavaScript自定义对象_第3张图片

 复杂类型作为函数的参数

【前端系列教程之JavaScript】06_JavaScript自定义对象_第4张图片

// 下面代码输出的结果?
// 构造函数
function Person(name,age,salary) {
  this.name = name;
  this.age = age;
  this.salary = salary;
}

// 普通函数
function f1(person) { // person为形参
  person.name = "lisi"; 
  person = new Person("aa",18,10); 
}

var p = new Person("zhangsan",18,1000);
console.log(p.name); // zhangsan
f1(p); // 把p对应的地址复制一份给person,person和p对应一个地址,那么修改地址对应的内容,会影响p
console.log(p.name); // lisi
//1. 
var num1 = 10;
var num2 = num1; // num2 = 10;
num1 = 20;
console.log(num1); // 20
console.log(num2); // 10

//2. 
var num = 50;
function f1(num) {
    num = 60;
    console.log(num);
}
f1(num); // 60
console.log(num); // 50

你可能感兴趣的:(#,javascript,前端,typescript,JS)