一、直接建立(经常使用)数组
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);
复制代码