文章目录
Object 对象操作
简介
面向对象的三大特征:封装
、继承
、多态
,但是 js 没有多态,所以它不是纯面向对象的语言
增、删、减、改
- 增加就是赋值
obj.属性 = 属性值
//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();
-
删减用关键字
delete
,delete.对象名.对象中的属性名
,只能删关键字delete obj.name;
这个方法不可以 把对象给删了,比方说
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);
- 浅拷贝:继承的不会被拷贝,只会拷贝自己的
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);
var obj4 = Object.assign(1);
//数字转对象
console.log(obj4);
//Number {1}
console.log(new Number(1));
//Number {1}
多个数组捏在一起
- 继承的不会被拷贝,只会拷贝自己的
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 他会强制转换成 stringvar obj = { 125:"ass" }; //这样也是可以的,但是要注意强转 console.log(obj[125]);
-
提取键值对:用
Object.entries(obj)
来提取键值对,返回的是个二维数组
var obj = {
name:"斯蒂芬库里",
elName:"终极牛逼三分球",
age:30,
say:"yes"
};
console.log(Object.entries(obj));
//(4) [Array(2), Array(2), Array(2), Array(2)]
二维数组 / 对象互相转化
- 用
Object.fromEntries
,可以将二维数组转化成对象
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
继承来的属性
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
继承来的。
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
前后都要有值,返回布尔变量,相当于 “ 谁 是不是 啥类型的 ”
var arr = [1,2,3,4];
/*判断具体的对象*/
console.log(arr instanceof String);
console.log(arr instanceof Array);
//false
//true
“类” 的创建
es5中没有 类 的具体实现,行规是在 function
后 首字母大写 类的单词名
构造函数
/*1.构造函数*/
function Person(name) {
/*关键点是this*/
this.name = name;
/*私有属性*/
var a = 1;
}
/*要new 实例化*/
var james = new Person("james");
console.log(james.name);
原型 prototype
作用:向对象中添加属性
原型其实也是个对象,在实例化之后,就会生出来,相当于 爹
function Person(){
}
//向 Person 类中添加 show 方法
Person.prototype.show = function(){
console.log(1);
};
//实例化 詹姆斯 对象
var james = new Person;
//展示詹姆斯的方法
james.show();
以下是新写的一个冒泡排序
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]
工厂模式
//这是一个小栗子
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");
// 工厂模式
function Tab(){
//添加原料
let obj = {};
//加工原料
obj.tablength = 1;
obj.psFor = function(){
console.log("psFor....");
}
//出厂
return obj;
}
例子:原版
<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>
例子优化:提取类
// 优化
<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>
‘类’ 方法
类方法只能用类去调用
通过类实例化的对象,是不能调用类方法的
function Person() {
}
Person.show = function () {
alert(1);
};
Person.show();
//类方法只能用类调用
继承
原型继承
原型的继承,就是,如果我实例化的对象有这个属性,就用实例化的,没有的话就去找他爹,也就是原型的
Object.prototype = {}
这个是爹
每次实例化一个对象,都会自动生成个 Object.prototype = {}
自己有找自己的,没有找原型(他爹的),这也相当于一个继承
在找不到就继续往上层 Object 中找方法(原型链)
//比方说我给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
对比
//这个是取消实例化的复制之后
function Person () {
}
Person.prototype.name = "father";
var p = new Person();
console.log(p.name)
//father
Call & Apply 方法
二者都可以实现继承,区别在于:
call
传参是逗号分开apply
传参是用数组
实质是在 操作指针
建议使用 方法.call(对象);
目的是让这个方法指向对象
//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)
var obj1 = {
name:"库里"
};
var obj2 = Object.create(obj1);
console.log(obj2.name);
//库里
console.log(obj2);
//{}
模拟继承
思想:把要继承的属性都 复制 到想要继承的人的身上,实质上类似于复制🤖
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 出来一个电脑(电脑是‘类’),你一台,我一台,(这就是实例化),我给我的电脑安装个软件(实例化对象的属性),但是你没有(另一个实例化对象),你就不能用这个软件