一、直接建立(經常使用)數組
let obj = {
name: '哈哈',
gender: '男'
}
複製代碼
二、使用實例化對象的方式建立(比較少用)app
function Foo() {
//
}
let foo = new Foo()
複製代碼
三、內置對象的實例函數
let x1 = new Object(); // A new Object object
let x2 = new String(); // A new String object
let x3 = new Number(); // A new Number object
let x4 = new Boolean(); // A new Boolean object
let x5 = new Array(); // A new Array object
let x6 = new RegExp(); // A new RegExp object
let x7 = new Function(); // A new Function object
let x8 = new Date(); // A new Date object
複製代碼
四、使用工廠方式建立(不多用)工具
function CreatePerson(name, age, sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function () {
return this.name;
}
return obj;
}
let p1 = new CreatePerson('哈哈', 20, '男');
複製代碼
一、每個對象都有連接着原型對象的隱藏屬性__proto__
測試
var obj = {};
obj.__proto__ === Object.prototype; //true
複製代碼
二、判斷一個對象是否包含一個屬性ui
const obj2 = {gender: '男'};
console.log('gender' in obj2);
console.log('name' in obj2);
// 也可使用hasOwnProperty
console.log(obj2.hasOwnProperty('gender'));
複製代碼
三、判斷一個對象是否爲空this
const obj2 = {gender: '男'};
console.log(Object.keys(obj2));
console.log(Object.values(obj2));
複製代碼
四、刪除一個屬性spa
const obj2 = {gender: '男', age: 20, name: '張三'};
delete obj2.gender;
console.log(obj2);
// 也可使用解析賦值的方式
const {name, ...obj1} = obj2;
console.log(obj1);
複製代碼
四、Object.assign()
的使用prototype
五、判斷是否爲對象代理
Object.prototype.toString.call(data).slice(8, -1)
複製代碼
一、constructor
查找該對象是由什麼建立出來的
let obj = {};
let reg = new RegExp();
let arry = new Array();
let str = new String();
let date = new Date();
console.log(obj.constructor);
console.log(reg.constructor);
console.log(arry.constructor);
console.log(str.constructor);
console.log(date.constructor);
// 繼續往上面找
console.log(Date.constructor);
console.log(Function.constructor);
複製代碼
二、instanceof
判斷構造函數是否在對象實例的原型鏈上
Person.prototype.dance = function () {
return 'dance function';
}
// 定義一個子類
function Foo() {
}
Foo.prototype = new Person();
let foo = new Foo();
/** * 修改Foo原型的constructor * 關於defineProperty幾個參數的介紹 * 第一個參數:屬性所在的對象,第二個參數:屬性的名字,一個描素符對象 */
Object.defineProperty(Foo.prototype, 'constructor', {
writable: false,
enumerable: false,
value: Foo,
});
let foo1 = new Foo();
console.log(foo1 instanceof Foo);
console.log(foo1 instanceof Person);
console.log(foo1 instanceof Object);
複製代碼
三、hasOwnProperty()
判斷一個對象是否擁有該屬性
var obj = {name: '哈哈', gender: '男'};
obj.hasOwnProperty('name');
複製代碼
四、setPrototypeOf()
修改對象的原型
function Foo() {
};
const foo = new Foo();
// 每個對象都有constructor
let bar = {};
console.log(bar.constructor);
// 修改bar的原型
Object.setPrototypeOf(bar, foo);
console.log(bar.constructor); // [Function: Foo]
複製代碼
一、configurable
: 若是爲true表示能夠修改與刪除屬性,若是爲false
就不能修改與刪除
二、enumerable
: 若是爲true表示爲可枚舉的可使用for..in
三、value
:指定屬性的值
四、writable
:若是爲true
表示能夠經過賦值語句修改對象屬性
五、get
定義gettter
函數
六、set
定義setter
函數
七、測試案例
let obj1 = {};
obj1.name = '哈哈';
obj1.gender = '男';
// 定義第三個屬性
Object.defineProperty(obj1, 'address', {
configurable: false,
enumerable: true,
value: '深圳',
writable: false,
});
console.log(JSON.stringify(obj1));
for (let key in obj1) {
console.log(`${key}===${obj1[key]}`);
}
複製代碼
一、對象的私有屬性
function Foo() {
let name;
// 定義一個set方法賦值
this.setName = (newVal) => name = newVal;
// 定義一個get方法取值
this.getName = () => name;
}
let foo = new Foo();
foo.setName('哈哈');
console.log(foo.getName());
複製代碼
二、對象的set
和get
方法
// 在對象中get與set只是在屬性前面加上了一個關鍵詞,可是依然是屬性的方式調用
const obj1 = {
name: '哈哈',
get getName() {
console.log('get方法');
return this.name;
},
set setName(newVal) {
this.name = newVal;
}
};
console.log(obj1.getName);
// obj1.setName = '張三';
// console.log(obj1.getName);
console.log(obj1.name);
複製代碼
三、使用defineProperty
定義私有屬性
function Foo() {
let _age = 0;
// 擴展一個屬性
Object.defineProperty(this, 'age', {
get() {
return _age;
},
set(newVal) {
_age = newVal;
}
})
}
let foo = new Foo();
console.log(foo.age);
foo.age = 10;
console.log(foo.age);
複製代碼
四、使用set
和get
進行數據的校驗
function Foo() {
let _age = 0;
Object.defineProperty(this, 'age', {
get() {
return _age;
},
set(newVal) {
if (/\d+/.test(newVal)) {
_age = newVal;
} else {
throw new TypeError('必須是數字');
}
}
})
}
try {
let foo = new Foo();
console.log(foo.age);
foo.age = 10;
console.log(foo.age);
foo.age = '哈哈';
} catch (e) {
console.log(e);
}
複製代碼
一、關於使用new
關鍵詞建立對象所發生的事情
二、爲何要使用構造函數的原型
在使用構造函數建立對象的時候,每
new
一次就會建立一個對象,不一樣的實例的同名函數是不相等的,所以建立不少重複的代碼(每次new一個構造函數,上面的構造函數就會執行一次,就會在內存中開闢一塊空間,指向新的堆對象,這樣內存消耗比較大),咱們但願代碼儘量的複用,就須要原型
// 普通的建立一個構造函數
function Animal(name, age) {
this.name = name;
this.age = age;
this.print = function() {
console.log(`${this.name}====${this.age}`);
}
}
// 使用原型
function Animal(name, age) {
this.name = name;
this.age = age;
}
Animal.prototype.print = function() {
console.log(`${this.name}====${this.age}`);
}
複製代碼
三、全部的對象都有一個constructor
指向原型
四、構造函數都有prototype
指向原型
ES6
前的版本)在面向對象開發中繼承的概念是,新對象複用舊對象上的屬性和方法(有點相似拷貝
Object.assign)
,相似生活中子繼承父的財產及工具的概念
一、一個構造函數的原型指定另一個構造函數
function Person() {
}
// 定義原型
Person.prototype.dance = function () {
return 'dance function';
};
// 定義一個子類
function Foo() {
}
Foo.prototype = Person.prototype;
// 總結:採用這種方式來建立類的繼承,只是地址指向(一個修改了,另一個也會隨之修改)
複製代碼
二、一個構造函數的原型指定另一個函數的實例對象
function Person() {
}
// 定義原型
Person.prototype.dance = function () {
return 'dance function';
};
// 定義一個子類
function Foo() {
}
// Foo構造函數的原型指向Person的實例對象
Foo.prototype = new Person();
let foo = new Foo();
console.log(foo.dance());
// 這樣繼承的方式會形成Foo的原型丟失,直接指定了Person
console.log(foo.constructor);
console.log(foo instanceof Foo);
// 總結:採用這種方式實現繼承:形成Foo的原型丟失,直接指定了Person
複製代碼
三、修正方式二中constructor
的指向
function Person() {
}
Person.prototype.dance = function () {
return 'dance function';
}
// 定義一個子類
function Foo() {
}
Foo.prototype = new Person();
let foo = new Foo();
console.log(foo.constructor);
// 修改Foo原型的constructor
Object.defineProperty(Foo.prototype, 'constructor', {
writable: false,
enumerable: false,
value: Foo,
});
let foo1 = new Foo();
console.log(foo1.constructor);
// 總結:修正`constructor`的指向
複製代碼
class
的方式建立類一、建立一個類
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
// 普通方法
say() {
return 'say...';
}
// 靜態方法
static talk() {
console.log(this);
return '我是靜態方法';
}
}
let p = new Person('哈哈', 20);
console.log(Person.talk());
複製代碼
二、實現類的繼承
class Animal {
constructor(name) {
this.name = name;
}
call() {
return '在叫';
}
}
class Dog extends Animal {
constructor(name, age) {
super(name);
this.age = age;
}
// 重寫父類的方法
call() {
return `${this.name}在叫`;
}
}
let dog = new Dog('大黃狗', 3);
console.log(dog.call());
複製代碼
三、使用set
和get
方法
class Person {
constructor() {
this.name = '哈哈';
}
set setName(newVal) {
this.name = newVal;
}
get getName() {
return this.name;
}
}
let p = new Person();
console.log(p.getName);
p.setName = '張三';
console.log(p.getName);
複製代碼
Proxy
的使用Proxy
是ES6
中新增的對象,使用方式Proxy(目標對象,代理的對象)
主要有以下屬性
get(target, propKey, receiver)
:攔截對象屬性的讀取,好比√proxy.foo和proxy['foo']√。
set(target, propKey, value, receiver)
:攔截對象屬性的設置,好比proxy.foo = v
或proxy['foo'] = v
,返回一個布爾值。
has(target, propKey)
:攔截propKey in proxy
的操做,返回一個布爾值。
deleteProperty(target, propKey)
:攔截delete proxy[propKey]
的操做,返回一個布爾值。
ownKeys(target)
:攔截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in
循環,返回一個數組。該方法返回目標對象全部自身的屬性的屬性名,而Object.keys()
的返回結果僅包括目標對象自身的可遍歷屬性。
getOwnPropertyDescriptor(target, propKey)
:攔截Object.getOwnPropertyDescriptor(proxy, propKey)
,返回屬性的描述對象。
defineProperty(target, propKey, propDesc)
:攔截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs)
,返回一個布爾值。
preventExtensions(target):攔截
Object.preventExtensions(proxy)`,返回一個布爾值。
getPrototypeOf(target):攔截
Object.getPrototypeOf(proxy)`,返回一個對象。
isExtensible(target)
:攔截Object.isExtensible(proxy)
,返回一個布爾值。
setPrototypeOf(target, proto)
:攔截Object.setPrototypeOf(proxy, proto)
,返回一個布爾值。若是目標對象是函數,那麼還有兩種額外操做能夠攔截。
apply(target, object, args)
:攔截 Proxy 實例做爲函數調用的操做,好比proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)
。
construct(target, args)
:攔截 Proxy
實例做爲構造函數調用的操做,好比new proxy(...args)
一、使用案例
let targetObj = {name: '哈哈'};
const proxy = new Proxy(targetObj, {
set(target, key, val) {
console.log(target);
console.log(key);
console.log(val);
target[key] = val;
},
get(target, key) {
console.log(target);
console.log(key);
return key in target ? target[key] : '不存在這個key';
},
// 使用in的時候調用
has(target, key) {
console.log(target, key)
if (target.hasOwnProperty(key)) {
return true;
} else {
return false;
}
},
deleteProperty(target, key) {
if (target.hasOwnProperty(key)) {
return true;
} else {
return false;
}
}
});
複製代碼
二、代理方法
let targetObj = function () {
return '目標函數';
};
let proxy = new Proxy(targetObj, {
apply(target, ctx, args) {
console.log(target());
console.log(ctx);
console.log(args);
return 'apply 函數';
}
});
proxy(12, 20);
複製代碼