JS-对象

125 阅读3分钟

创建对象方法

一、对象字面量/对象直接量

对象中,this指向对象本身,可以通过this调用本对象内的其他属性和方法。

var teacher = {
    name: 'jackson',
    age: 25,
    sex: 'male',
    weight: 130,
    teach: function(){  //方法
        console.log('I am teaching javascript');
    },
    eat: function(){
        this.weight++;
        console.log('I am having a dinnner');
    }
}
teacher.teach(); //调用
teacher.height = 174; //增
delete teacher.teach;//删
teacher.name = 'win'; //改
console.log(teacher.sex); // 查

并且方法是可以传参的

var attendance = {
    students: [],
    total: 6,
    join: function(name){
        this.students.push(name);
        if(this.students.length === this.total){
            console.log(name + '到课,学生已到齐');
        }else{
            console.log(name + '到课,学生未到齐');
        }
    },
    leave: function(name){
        var idx = this.students.indexOf(name);
        if(idx !== -1){
            this.students.splice(idx, 1);
        }
        console.log(name + '早退');
    },
    classOver: function(){
        this.students = [];
        console.log('已下课')
    }
}
attendance.join('jackson');

二、构造函数,通过new关键字实例化一个对象

对象和构造函数是不一样的,对象是通过实例化构造函数而创建的对象实例

  1. 用系统自带的构造函数

和对象字面量是一样的,只是形式不同

var obj = new Object();
obj.name = 'eden';
obj.sex = 'female';

这种方式和字面量一样,原型指向的都是Object

  1. 自定义构造函数

和普通的函数没有什么区别,就是命名用大驼峰和普通函数区别开。原型是自定义构造函数对应的原型。

function Teacher(){
    this.name = 'jackson';
    this.sex = 'male';
    this.weight = 130;
    this.teach = function(){
        console.log('I am teaching javascript');
    }
    this.eat = function(){
        this.weight++;
        console.log(this.weight);
    }
}
var teacher = new Teacher();

没执行之前,this根本就没生成,要让this存在,必须要用new实例化

this指向实例化出来的对象,new出来的不同实例对象相互之间不影响

每次都手动修改值不现实,所以我们可以传参

function Teacher(name, sex, weight){
    this.name = name;
    this.sex = sex;
    this.weight = weight;
    this.teach = function(){
        console.log('I am teaching javascript');
    }
    this.eat = function(){
        this.weight++;
        console.log(this.weight);
    }
}
var teacher1 = new Teacher('jackson', 'male', '130');
var teacher2 = new Teacher('hendery', 'male', '140');

teacher1.eat(); //131
teacher2.eat(); //141

也可以只传入一个对象(封装插件),更好维护

function Teacher(opt){
    this.name = opt.name;
    this.sex = opt.sex;
    this.weight = opt.weight;
    this.teach = function(){
        console.log('I am teaching javascript');
    }
    this.eat = function(){
        this.weight++;
        console.log(this.weight);
    }
}
var teacher1 = new Teacher({
    name: 'jackson',
    sex: 'male',
    weight: 130
});

链式操作

有return this(回到对象本身)就可以链式操作

var sched = {
	wakeup: function(){
		console.log('running');
		return this;
	},
	morning: function(){
		console.log('eating');
		return this;
	},
	noon: function(){
		console.log('resting')
		return this;
	}
}
sched.wakeup().morning().noon();

对象属性访问

最早的JS引擎对对象的处理都是obj['name']

有了点语法之后会隐式转换 obj.name -> obj['name'],做字符串拼接的时候一定要用[]

var myLang = {
    NO1: 'HTML',
    NO2: 'CSS',
    NO3: 'JS',
    myStudy: function(num){
        console.log(this['NO' + num]);
    }
}
myLang.myStudy(1);

对象属性遍历(枚举)

for in循环

var car = {
    brand: 'benz',
    color: 'green',
    width: '2.5'
}

for(var key in car){
    console.log(key + ':' + car[key]);
}

car.key无法访问的原因是:会经过一层转换

car.key -> car['key'] -> undefined

for in既可以遍历对象也可以遍历数组(数组是特殊的对象)

var arr = [1, 2, 2, 5];
for(var i in arr){
    console.log(arr[i]);
}

hasOwnProperty 找对象自身的属性,排除原型上的属性

var obj = {
    name: 'jack',
    age: 25
}
console.log(obj.hasOwnProperty('name'));  //true

for in循环原型链上的所有属性都能打印出来

function Car(){
	this.brand = 'benz',
	this.color = 'red'
}
Car.prototype = {
	lang: 5
}
Object.prototype.name = 'object';
var car = new Car();
for(var key in car){
	console.log(key + ':' + car[key]); //会把原型链上自定义的属性也打印出来
}

如果只想打印对象自己的属性,就需要hasOwnProperty了

for(var key in car){
	if (car.hasOwnProperty(key)) {
		console.log(key + ':' + car[key]);
	}
}

in 不排除原型(没啥用)

var car = {
	brand : 'benz',
	color : 'red'
}
console.log('displacement' in car);  //false

'displacement' -> car['displacement'],一定要加引号!

function Car(){
	this.brand = 'benz',
	this.color = 'red'
}
Car.prototype = {
	displacement : 3.0
}
var car = new Car();
console.log('displacement' in car);  //true

instanceof 判断该对象是不是该构造函数实例化出来的

function Car(){
	this.brand = 'benz',
	this.color = 'red'
}
var car = new Car();
console.log(car instanceof Car);  //true
console.log(car instanceof Object);  //true
console.log([] instanceof Array);  //true

也就是说原型链有重复的部分都是true

判断是否是数组的三种方法

var a = [];
console.log(a.constructor);
console.log(a instanceof Array);
var str = Object.prototype.toString.call(a);
console.log(str); //[object Array]

一般用toString方法进行判断

Object.prototype.toString.call()

Array和Object的原型上都有toString方法,但是得出的结果不一样,用Object的原型方法才知道是哪种数据类型

后台传过来的数据有可能是:

  1. null
  2. json
[ { name: 'abc' },    { name: 'bac' } ]
  1. 错误信息
{ '10061': 'error'}

判断是那种信息,进行针对处理

var str = Object.prototype.toString.call(a),
    trueTip =  '[object Array]'
if(str === trueTip){
    console.log('是数组');
}else{
    console.log('不是数组')
}