主要是Object对象上的方法,以及其创建的实例上方法。 通常可以用在不同实例对象上的方法。
将一个对象上的方法拷贝到另一个对象上
function Fruit(name) {
this.name = name;
}
Fruit.prototype.sayName = function () {
console.log(this.name);
}
var Apple = {
color:"red"
}
var ft = new Fruit("apple");
Object.assign(Apple,ft); // 将ft对象上的属性和方法复制到Apple上
console.log(Apple);
获取对象所有(可枚举)属性名的数组,对象原型上的属性不能获取。
function Plant(){
this.desc = "植物类"
}
Plant.prototype.sayHi = function () {
console.log("hi");
}
function Apple() {
this.desc = "我是一个大苹果";
Plant.call(this);
}
Apple.prototype = Object.create(Plant.prototype);
Apple.prototype.constructor = Apple;
// 使用Object.keys()
var bigApple = new Apple();
console.log(bigApple); // Apple{desc: "植物类"}
console.log(Object.keys(bigApple)); // ["desc"]
获取对象本身的属性,不包括对象原型上的属性
console.log(Object.getOwnPropertyNames(bigApple)); // ["desc"]
获取对象的原型
function Plant(){
this.desc = "植物类"
}
var obj = new Plant();
console.log(obj.__proto__ === Object.getPrototypeOf(obj)); // true
console.log(Plant.prototype === Object.getPrototypeOf(obj))// true
等价于实例的__proto__
属性
设置对象的原型
// 创建两个对象
var obj1 = {
name:"obj1"
};
var obj2 = {
age:18
}
Object.setPrototypeOf(obj1,obj2);
console.log(Object.getPrototypeOf(obj1) === obj2); // true
将obj1对象的原型设置为obj2
new一个对象的原理其实是:
1.创建一个空对象obj
2.将该对象原型设置为Plant.prototype
3.使用构造函数Plant
初始化对象。(调用构造函数修改this指向为obj对象即可)
function Plant(){
this.desc = "植物类"
}
// var plt = new Plant;
var obj = {};
Object.setPrototypeOf(obj,Plant.prototype);
Plant.call(obj);
console.log(obj.desc); // 植物类
console.log(obj instanceof Plant); // true
传入一个对象,以这个对象为原型创建一个新对象
var obj1 = {
name:"obj1"
};
var obj2 = Object.create(obj1);
// getPrototypeOf查看原型对象
console.log(Object.getPrototypeOf(obj2) === obj1); // true
对象实例上的方法
只有在计算式中,对象调用这个方法,将对象转换成值
var obj1 = {
name:"obj1"
};
console.log(obj1.valueOf()); // {name: "obj1"}
obj1.valueOf = function () {
return 3;
}
console.log(obj1+2); // 5
返回一个对象的字符串形式,默认返回类型字符串
var obj1 = {
name:"obj1"
};
function fn() { };
var date = new Date();
console.log(obj1.toString()); // [object Object] 对象-》对象类型
console.log(String("33").toString()); // 33 字符串=》字符串本身
console.log(Number(128).toString()); // 128 数字=》值
console.log([1,3,5].toString()); // 1,3,5 数组=》使用,连接每个数组每个元素,相当于调用join(",")
console.log(fn.toString()); // function fn() { } 函数=》函数内容
console.log(date.toString()); // Sat May 09 2020 19:09:55 GMT+0800 (中国标准时间) 时间=》时间戳
对于不同类型的对象,返回不同的值
使用本地的习惯定义返回值。通常对时间、数组、数字定制了该方法
// toLocalString
console.log(Number(128).toLocaleString()); // 128
console.log([1,3,5].toLocaleString()); // 1,3,5
console.log(date.toLocaleString()); // 2020/5/9 下午7:13:24 时间=》时间戳 使用当地习惯的时间表示方法
判断a是否是b的原型
var obj1 = {
name:"obj1"
};
var obj2 = {
age:18
}
Object.setPrototypeOf(obj1,obj2); // 设置obj1的原型是obj2
console.log(obj2.isPrototypeOf(obj1)); // true
console.log(Object.prototype.isPrototypeOf(obj1)); // true Object.prototype是obj1的原型
其实,根据原型链解释,Object.prototype
是所有对象的原型对象。
判断该实例是否有自己的属性
var obj1 = {
name:"obj1"
};
var obj2 = {
age:18
}
Object.setPrototypeOf(obj1,obj2); // 设置obj1的原型是obj2
console.log(obj1.hasOwnProperty("name")); // true
console.log(obj1.hasOwnProperty("age")); // false
这个方法是用来判断一个属性是否是该对象自己的方法,而不是继承过来的方法。
属性对象描述符,通常是用来控制对象的一个属性是否可以修改、删除、枚举等操作。
获取对象上的一个属性的属性描述符
参数一为一个对象,参数二为对象上的一个属性
var obj1 = {
name:"haha"
}
// 查看obj1对象的name属性的属性描述符
console.log(Object.getOwnPropertyDescriptor(obj1,"name"));
//结果{value: "haha", writable: true, enumerable: true, configurable: true}
console.log(obj1.propertyIsEnumerable("name")); // true
获取可枚举属性和不可遍历的属性
var obj1 = {
name:"haha"
}
Object.defineProperty(obj1,"age",{
value:18,
writable:false,
enumerable:true
})
console.log(Object.getOwnPropertyNames(obj1)); // ["name", "age"]
判断对象是否可枚举,只能判断对象本身的属性,不可枚举的属性或者继承的属性一律返回false
具体可设置的属性如下
属性名 | 值 | 作用 |
---|---|---|
value | “haha” | 对象的值 |
writable | true | 设置该属性是否可写 |
enumerable | true | 设置该属性是否可枚举(例如:for in 遍历对象时,遍历到这个属性) |
configurable | true | 是否可配置,对象能否删除 |
set | undefined | 设置对象属性时调用,例如:obj.name=123 |
get | undefined | 获取对象属性时调用,例如:obj.name |
注意
定义对象上属性的属性描述符
参数为对象,参数二为属性,参数三为对象描述符
var obj1 = {
name:"haha"
}
Object.defineProperty(obj1,"age",{
value:18,
writable:false,
enumerable:true
})
console.log(Object.getOwnPropertyDescriptor(obj1,"age"));
//结果:{value: 18, writable: false, enumerable: true, configurable: false}
对于没有定义的属性描述符,默认为false
定义多个对象属性的属性描述符
参数一为对象,参数二为键值对列表(键为属性名,值为属性描述符)
var obj1 = {
name:"haha"
}
Object.defineProperties(obj1,{
p1:{
value:"hello",
writable:true
},
p2:{
get:function () {
return this.name + " is sb"
},
set:function(newVal){
console.log("set");
this.name = newVal
}
}
})
console.log(Object.getOwnPropertyDescriptor(obj1,"p1"));
// {value: "hello", writable: true, enumerable: false, configurable: false}
console.log(Object.getOwnPropertyDescriptor(obj1,"p2"));
// {enumerable: false, configurable: false, get: ƒ, set: ƒ}
console.log(obj1.p2); // haha is sb
obj1.p2 = "apple"; // set
js有基本数据类型和引用数据类型
基本数据类型使用等号,直接复制对象
let a = 22;
let b = a;
b = 4;
console.log(a); // 22
console.log(b); // 4
b复制了a的值之后,与原对象a就没有任何关系。b的值修改,a的值也不会变。
如果是引用类型(对象、数组),直接复制,变量获得的是对象的内存地址,而不是对象的值
// 案例一
let arr1 = [1,4,5];
let arr2 = arr1;
arr2.push(66);
console.log(arr1); // [1, 4, 5, 66]
console.log(arr2); // [1, 4, 5, 66]
// 案例二
let obj1 = {
name:"apple",
age:12
};
let obj2 = obj1;
obj2.name = "banana";
console.log(obj1); // {name: "banana", age: 12}
console.log(obj2); // {name: "banana", age: 12}
对对象的属性依次遍历,判断是否是一个对象,是则递归遍历;不是,则复制到新对象上。
function deepCopy(oldObj,newObj) { //oldObj:被复制的对象 newObj:新对象,复制到这个对象中
for(key in oldObj){
// hasOwnProperty判断这个属性是否是自己的属性,而不是继承过来的
if(oldObj.hasOwnProperty(key)){
if(oldObj[key] && typeof oldObj[key] === "object"){
// 判断是数组还是对象
newObj[key] = oldObj[key].constructor === Array?[]:{};
// 继续递归,将数组/对象中的值赋值到新对象中
deepCopy(oldObj[key],newObj[key]);
}else{ // 如果是一个属性,则直接复制到新对象
newObj[key] = oldObj[key];
}
}
}
return newObj
}
var obj1 = {
name:"apple",
color:['blue','green'],
prop:{
num:12
}
};
var obj2 = deepCopy(obj1,{});
console.log(obj1); // {name: "apple", color: Array(2), prop: {…}}
console.log(obj2); // {name: "apple", color: Array(2), prop: {…}}
obj2.name = "banana";
obj2.color.pop();
console.log(obj1); // {name: "apple", color: Array(2), prop: {…}}
console.log(obj2); // {name: "banana", color: Array(1), prop: {…}}