Object 对象操作

简介

面向对象的三大特征:封装继承多态,但是 js 没有多态,所以它不是纯面向对象的语言

增、删、减、改

  • 增加就是赋值 obj.属性 = 属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//ES6 的对象简写模式
function simpleWrite() {
let name = "斯蒂芬库里";
let str = "string";
let functionName = "realFunName";
let obj = {
name,
//简写,key为name,value为斯蒂芬库里

[str]: "key值放变量",
//这里的key可以放个变量了

["a" + "bc"]: "key值放运算",
//key值很自由了,可以运算,所以可以通过循环生成一组key了

[functionName]() {},
//函数名字也可以用变量
};
console.log(obj["name"]);
//斯蒂芬库里

console.log(obj["string"]);
//调用的时候用字符串

console.log(obj[functionName].name);
//realFunName
//拿出真实名字
//没啥屁用
}
simpleWrite();
  • 删减用关键字 deletedelete.对象名.对象中的属性名,只能删关键字

    1
    delete obj.name;

    这个方法不可以 把对象给删了,比方说

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var obj = {
    0: "ass",
    /*在obj中先转换成字符串*/
    name: "xiaoming",
    hab: [],
    show: function () {
    console.log(this.name);
    },
    };
    //对象这样删除是删不掉的
    delete obj;
    obj.show();
  • 同名才需要修改,修改也就是重新赋值,比方说我要修改 obj.name 直接再次赋值即可

  • 查询属性的话就是输出,console.log(obj.name);,查询函数的话就是调用,obj.show();

Object.assign()

两个对象拼接

  • 类方法:Object.assign(obj1,obj2);
  • 浅拷贝:继承的不会被拷贝,只会拷贝自己的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const obj1 = {
a: 1,
};
const obj2 = {
b: 2,
};
var obj3 = Object.assign(obj1, obj2);

console.log(obj1);
//{a: 1, b: 2}
//这里 obj1 也发生了变化

console.log(obj2);
//{b: 2}

console.log(obj3);
//{a: 1, b: 2}

数字转对象

  • 相当于 new Number(1);
1
2
3
4
5
6
7
var obj4 = Object.assign(1);
//数字转对象

console.log(obj4);
//Number {1}
console.log(new Number(1));
//Number {1}

多个数组捏在一起

  • 继承的不会被拷贝,只会拷贝自己的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var obj1 = {
a: 1,
};
var obj2 = {
b: 2,
};
var obj3 = {
c: 3,
};
var tar = {};
//想要把obj1、2、3整理到tar里
const sors1 = (tar, ...arr) => Object.assign(tar, ...arr);

//也可以
//新建一个空数组{},然后后把...arr放到新的{}中
const sors2 = (...arr) => Object.assign({}, ...arr);

console.log(sors1(tar, obj1, obj2, obj3));
//{a: 1, b: 2, c: 3}

console.log(tar);
//{a: 1, b: 2, c: 3}
//原先 tar 不是空的么,用了sors1方法,就会改变它

//想要不改变tar,那么就新开一个变量
console.log(sors2(obj1, obj2, obj3));
//{a: 1, b: 2, c: 3}

提取键、值、键值对

  • 提取键:用 Object.keys(obj) 来提取,返回数组,并且每个值都是 ?字符串

  • 提取值:用 obj[Object.keys(obj)[1]]; 来取值,实质是用关键字来取值,也就是 obj[key]

    注意:
    一般 obj[key]key 必须是 string,然而如果是数字的话,obj 他会强制转换成 string

    1
    2
    3
    4
    5
    var obj = {
    125: "ass",
    };
    //这样也是可以的,但是要注意强转
    console.log(obj[125]);
  • 提取键值对:用 Object.entries(obj)来提取键值对,返回的是个二维数组

1
2
3
4
5
6
7
8
var obj = {
name: "斯蒂芬库里",
elName: "终极牛逼三分球",
age: 30,
say: "yes",
};
console.log(Object.entries(obj));
//(4) [Array(2), Array(2), Array(2), Array(2)]

二维数组 / 对象互相转化

  • Object.fromEntries,可以将二维数组转化成对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var obj = {
name: "斯蒂芬库里",
elName: "终极牛逼三分球",
age: 30,
say: "yes",
};
let { keys: k, values: v, entries: e } = Object;

var fE = Object.fromEntries([
["a", 1],
["b", 2],
]);
console.log(fE);
//{a: 1, b: 2}

var fE1 = Object.fromEntries([e(obj)]);
//二位数组变成对象
console.log(fE1);
//{name,斯蒂芬库里: Array(2)}

对象中的循环

for in 循环

对象中有专门的循环 for(var x in obj)

  • 这个是能拿到 prototype 继承来的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person() {
this.name = "Stephen Curry";
this.habit = ["sing", "dance", "rap"];
this.age = 18;
}
Person.prototype.string = "i'm superStart!";

var p = new Person();
for (var items in p) {
console.log(items);
//name
//habit
//age
//string
}

Object.keys()

  • 这个循环的时候是拿不到 prototype 继承来的。
1
2
3
4
5
6
7
8
9
10
11
12
function Person() {
this.name = "Stephen Curry";
this.habit = ["sing", "dance", "rap"];
this.age = 18;
}
Person.prototype.string = "i'm superStart!";

var p = new Person();

console.log(Object.keys(p));
//(3) ["name", "habit", "age"]
//没有string

长度

用 key 值的长度间接的测出 对象的长度 :Object.keys(obj).length

判断具体对象 *

关键字 instanceof 前后都要有值,返回布尔变量,相当于 “ 谁 是不是 啥类型的 ”

1
2
3
4
5
6
7
var arr = [1, 2, 3, 4];
/*判断具体的对象*/
console.log(arr instanceof String);
console.log(arr instanceof Array);

//false
//true

“类” 的创建

es5 中没有 的具体实现,行规是在 function首字母大写 类的单词名

构造函数

1
2
3
4
5
6
7
8
9
10
11
/*1.构造函数*/
function Person(name) {
/*关键点是this*/
this.name = name;

/*私有属性*/
var a = 1;
}
/*要new 实例化*/
var james = new Person("james");
console.log(james.name);

原型 prototype

作用:向对象中添加属性
原型其实也是个对象,在实例化之后,就会生出来,相当于

1
2
3
4
5
6
7
8
9
10
function Person() {}
//向 Person 类中添加 show 方法
Person.prototype.show = function () {
console.log(1);
};
//实例化 詹姆斯 对象
var james = new Person();

//展示詹姆斯的方法
james.show();

以下是新写的一个冒泡排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1];
Array.prototype.newSort = function () {
var len = this.length;
for (var i = 0; i < len; i++) {
for (var j = 0; j < len - i + 1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
};
arr.newSort();
console.log(arr);

// [1,2,3,4,5,6,7,8,9]

工厂模式

1
2
3
4
5
6
7
8
9
10
11
12
//这是一个小栗子
function HuaZP() {
var obj = new Object();
obj.name = "眼影";
obj.price = 1000;
obj.describe = function (data) {
console.log(data);
};
return obj;
}
var hzp = new HuaZP();
hzp.describe("2019-10-10");
1
2
3
4
5
6
7
8
9
10
11
12
//    工厂模式
function Tab() {
//添加原料
let obj = {};
//加工原料
obj.tablength = 1;
obj.psFor = function () {
console.log("psFor....");
};
//出厂
return obj;
}

例子:原版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<script>
/*工厂*/
var Factory = function(account){
function superAdmin() {
this.name = "超级管理员";
this.array = ["首页","商品","管理","购物车"];
}
function admin() {
this.name = "管理员";
this.array = ["首页","商品","管理"];
}
function user() {
this.name = "用户";
this.array = ["首页","商品"];
}

switch(account){
case "superAdmin":
return new superAdmin();
break;
case "admin":
return new admin();
break;
case "user":
return new user();
break;
default:
throw new TypeError("类型错误!!");
}
};

var ele = Factory("user");
console.log(ele.name + ':' + ele.array);
</script>

例子优化:提取类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 优化
<script>
var Factory = function (account) {
/*优化点在这里,提取出类来!*/
function User(opt) {
this.name = opt.name;
this.array = opt.array;
}

switch(account){
case "superAdmin":
return new User({name:"烧鸡管理员",array:["卤蛋","麻辣烫","烧花鸭","烧子鹅"]});
break;
case "admin":
return new User({name:"垃圾管理员",array:["卤蛋","麻辣烫","烧花鸭"]});
break;
case "user":
return new User({name:"调料管理员",array:["卤蛋","麻辣烫"]});
break;
default:
throw new TypeError("类型错误!!");
}
};
/*实例化对象*/
var people = Factory("superAdmin");
console.log(people.name + ":" + people.array);
</script>

‘类’ 方法

类方法只能用类去调用
通过类实例化的对象,是不能调用类方法的

1
2
3
4
5
6
7
8
function Person() {}

Person.show = function () {
alert(1);
};

Person.show();
//类方法只能用类调用

继承

原型继承

原型的继承,就是,如果我实例化的对象有这个属性,就用实例化的,没有的话就去找他爹,也就是原型的

Object.prototype = {} 这个是爹
每次实例化一个对象,都会自动生成个 Object.prototype = {}
自己有找自己的,没有找原型(他爹的),这也相当于一个继承
在找不到就继续往上层 Object 中找方法(原型链)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//比方说我给Person,通过原型,添加个name属性
function Person() {}
Person.prototype.name = "father";

//实例化一个p,类型为Person
var p = new Person();

p.name = "son";
//当我给实例化的对象的name 赋值时,输出的就是son
//而我不给实例化对象p的name赋值时,它首先会找自己里面有没有,没有的话找他的原型Person
//还没有的话接着往上找Object

console.log(p.name);
//son

对比

1
2
3
4
5
6
//这个是取消实例化的复制之后
function Person() {}
Person.prototype.name = "father";
var p = new Person();
console.log(p.name);
//father

Call & Apply 方法

二者都可以实现继承,区别在于:

  • call 传参是逗号分开
  • apply 传参是用数组

实质是在 ==操作指针==

建议使用 方法.call(对象); 目的是让这个方法指向对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//call 和 apply的使用例子
<script>
function Person() {
this.name = "xiaopang",
this.age = 19
}
function show(str1,str2) {
console.log(this.name + this.age + "hahhaa" + str1 + str2);
}
var p = new Person();
/*show继承了p*/
/*call方法直接用逗号隔开*/
show.call(p,"政府","你妹妹");

/*apply方法是用数组*/
show.apply(p,["string1","string2"]);

//输出
//xiaopang19hahhaa政府你妹妹
//xiaopang19hahhaastring1string2
</script>

Creat

这玩意也可以继承,但是只能继承属性(2019-11-14)

1
2
3
4
5
6
7
8
9
10
var obj1 = {
name: "库里",
};
var obj2 = Object.create(obj1);

console.log(obj2.name);
//库里

console.log(obj2);
//{}

模拟继承

思想:把要继承的属性都 复制 到想要继承的人的身上,实质上类似于复制 🤖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Object.prototype.jicheng = function (obj) {
for (var x in obj) {
/*追加*/
//this指的是调用的对象,obj就是从它身上扒属性,复制给this。
this[x] = obj[x];
}
};
function Father() {
this.name = "Father";
this.show = function () {
console.log("我爱洗澡");
};
}
function Son() {
this.age = "18";
}

var fa = new Father();
var son = new Son();

son.jicheng(fa);
console.log(son);
//Son {age: "18", name: "Father", show: ƒ, jicheng: ƒ}

举例理解实例化 和 类

比方说我 new 出来一个电脑(电脑是‘类’),你一台,我一台,(这就是实例化),我给我的电脑安装个软件(实例化对象的属性),但是你没有(另一个实例化对象),你就不能用这个软件