-
表现方式:对象是一组无序的原始数据(或引用数据类型)序列,并且这个序列以键值对的形式储存。序列中的每一项称之为属性(函数称之为方法),属性名必须是唯一的 【说明】:属性名可以是字符串或number,number必要用【】方括号。理由:特殊
2.对象的三个特征:封装、继承、多态
继承:js本没有继承机制,但是我们可以通过js的语法上的方法,来得到效果
多态:请求的方法中带不同的参数,可以返回不同的数据
3.理解对象:两个角度来看对对象:
a 从现实事物的角度来:对象是对现实事物的抽象
b 从具体数据的角度来:对象是对具体事物的封装。
补充一.遍历对象的属性 for in
var stu = { "name":"zhangsan", 10:10, "gender":"male", } for(var att in stu){ console.log(att); // 10 name gender console.log(`${att}:${stu[att]}`); //‘10’:10,name:‘zhangsan’,gender:'male' }
补充二:删除属性名 delete
delete stu.name;//即删除stu这个对象的叫name的属性
二 .引用数据类型和原始数据类型
区别: 内存分配不同。赋值方式不同
var stu = {
"name":"zhangsan",
10:10,
"gender":"male",
"num":{
"name":"zhang4"
}
}
浅拷贝:将一个对象赋值到另一个对象上,更改新对象的属性值,并不影响以前的对象的属性值
(局限:属性值是个具体的值,并非又是对象),如果属性值是对象(判断),再进行一次赋值
function clo(obj){ var nObj = {}; for(var attr in obj){ if(typeof obj[attr] === "object"){ nObj[attr] = clo(obj[attr])//深度拷贝 }else{ nObj[attr] = obj[attr]//浅拷贝 } } return nObj; } var nStu = clo(stu); nStu.num.name = "zhang5"; nStu[10] = 70;//单独改了nStu的属性 console.log(nStu); console.log(stu);
三.对象数据可具有的属性
每个数据属性除了拥有键值对的特性外,还有三个特性:可配置性、枚举性、可写性。默认的值都是false
3.1 可配置性(configurable) : 指明该属性是否可以被删除。(默认false,可以被删除)
3.2 枚举型 enumerable :默认false,隐藏(与display为none效果差不多)
3.3 可读性 writeable :默认false,不可以更改
var teah = {} //重新定义对象的属性(三个参数:对象名、对象的属性、操作) Object.defineProperty(teah, "name", { value: "mir li", configurable: true, //表示该属性是否可以被删除:用法暴露接口被别人,别人用不着,也不允许别人删除/默认是false,不可以被删除 enumerable: true ,//表示是否隐藏,默认false,隐藏,forin不能遍历 writeable: true //teah的这个“name”这个属性是否可以被改变,默认是false,不可以被改变 }) Object.defineProperty(teah, "age", { value: 30, // configurable: false, enumerable:true, // writeable:false }) //delete teah.age; teah.age = 56; teah.name = "chang";//并不能覆盖上面的"mir li",除非先删name属性(除用delete) console.log(teah);
四 .创建对象
4.1,对象式:创建JSON格式的对象,也称之为JSON式对象
var stu = {
name: "zhang3",
age: 21,
sayName: function() {
console.log(this.name)
}
}
stu.sayName();
4.2 函数构建对象:通过函数式来创建对象(工厂方法)
4.2.1 通过函数的返回值来创建对象
function getStu(name,age) {
return {
name: name,
age: age,
sayName: function() {
console.log(this.name)
}
}
}
var zhag3 = getStu("zhang3",22);
zhag3.sayName();
var lisi = getStu("lisi",30);
console.log(zhag3)
cnsole.log(lisi.name)
4.2.2 通过构造函数来创建,使用new关键字
function Student(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayName= function() {
console.log(this.name)
}
return obj;
}
var stu1 = new Student("lisi",80);
console.log(stu1);
stu1.sayName();
【注意:】通过函数来才创建的两种写法(冒号和等号)
Prototype 原型
-
作用:通过原型的方式来做继承
-
定义:每一个对象身上有一个proto的属性,这个属性是一个对象,指向的是构建这个对象的构造函数的prototype
-
函数与对象的关系:函数是对象的一种,对象是通过函数创建的 var arr = new Array(); arr[1] = "hello"; arr[2] = 56; arr[3] = true; console.log(typeof Array);//function,数组是对象,所有的对象是通过函数function来创建 console.log(typeof arr);//object //数组、函数都是object
-
从两个角度来:
把函数当做函数来看待,(每一个函数身上都有一个prototype);
把函数当做对象来看待(每一个对象身上有一个__proto__对象);
var obj = {};
var obj1 = new Function();
console.log(obj); //每一个对象身上有一个__proto__对象
console.log(obj1.prototype); //每一个函数身上都有一个prototype
var obj1 = function(){};
console.log(obj1.prototype); //两种方式创建的函数都有这个特性
function fn(){};
console.log(fn instanceof Object);
console.log(fn instanceof Function);//说明函数是对象的一种
(对象的proto instanceof 函数的prototype)
补充 instanceof运算符
对于值类型,用typeof就可以判断数据类型:string/number/boolean/null/undefine,但对于object,就只能返回object或function,并不能真正判断出是否会是一个数组。
判断规则:A instanceof B,沿着A的proto这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,就返回true,如果找到的终点还未重合,则返回false
var obj = new Object();
console.log(obj.__proto__ === Object.prototype);
//每一个对象都有一个__proto__这个属性,这个属性是一个对象,指向的是构建这对象的构造函数的prototype
继承:原型链
function Object(){} Object.prototype.name= "zhangsan"; Father.prototype = new Object(); function Father(){} // Father.prototype.name= "zhangsan"; Child.prototype = new Father(); function Child(){} var c1 = new Child(); console.log(c1.name); //理解原型链:打印c1.name,c1里没有name这个属性,但c1有个__proto__这个属性(沿着这个一层一层找上去),这个__proto__属性指向Child的prototype,Child.prototype.names没有定义,接着往上找,Child.prototype又是一个对象,也有__proto__这个属性,指向的是构建这个对象的构造函数Father的prototype。。。