var a = {}
字面量创建系统构造函数Object()
: var per = new Object()
自定义构造函数
function Person(name){
this.name = name,
this.age = 18
}
var person = new Person('limei')
new
关键字 会在构造函数内部:
var this ={}
;this.xxx = xxx
;return this
;Object.create()
方法:
Object.create(proto, [propertiesObject])
proto
:必需。新创建的对象的__proto__
。propertiesObject
:可选。如果该参数是一个对象,那么其自有可枚举属性(即那些自有属性且其enumerable
为true
的属性)的键值对会被添加到新创建对象的对应属性上,作为新创建对象的自有属性。这些属性的描述符由propertiesObject
中对应属性的值提供。
示例:
// 1.
const obj = Object.create(null) // obj 为 {}
console.log(emptyObject.__proto__); // 输出:undefined
// 2.
const person = {
sex: '男',
say: function () {
console.log(`${this.name}说:我今年${this.age}了,我的性别是:${this.sex}`)
}
}
const xiaoMing = Object.create(person, {
// 定义一个数据描述符
age: {
value: 19,
writable: true,
enumerable: true,
configurable: true
},
// 定义一个访问器描述符
look: {
get: function() {
return 'Hello, ' + this.name;
},
enumerable: true,
configurable: true
}
})
// 输出
xiaoMing.name = "小明"
xiaoMing.sex = "女"
xiaoMing.say() // 小明说:我今年19了,我的性别是:女
xiaoMing.look // 'Hello, 小明'
对象属性可以通过两种主要方式访问:点符号(.
)和方括号([]
)
// 1. 点符号(.)
let obj = {
name: 'Alice',
age: 30,
'my-prop': '自定义的属性'
};
console.log(obj.name); // 输出 'Alice'
console.log(obj.age); // 输出 30
// 2. 方括号([])
console.log(obj['age']) // 输出30
let propName = 'name';
console.log(obj[propName]); // 输出 'Alice'
console.log(obj['my-prop']) // 输出 自定义的属性
prototype
)obj.prototype
对象的原型(每个函数对象才会拥有prototype
)prototype
是函数对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承改原型的属性和方法,原型也是对象。__proto__
__proto__
属性,去访问自己的原型Object.prototype
var obj = Object.create(null)
; //obj
无原型,无__proto__
,无constructor
1. var obj = {};
obj.__proto__ = Object.prototype;
2. Person.prototype.name = '构造函数Person的原型'
function Person(){};
var person = new Person();
person.name; // 访问先查看自身属性,没有去其原型上查找
person.__proto__ ------> Person.prototype
constructor
属性,这个属性指向创建它的构造函数。
这样做的目的是为了在原型链上能够正确地追踪到实例的构造函数。
通常,当你定义一个构造函数并创建它的实例时,这个实例的constructor
属性会指向该构造函数。
function Person(name, age) {
this.name = name;
this.age = age;
}
// 构造函数上prototype的constructor指向自己
console.log(Person.prototype.constructor === Person); // 输出: true
// 创建一个Person实例
let person = new Person('Alice', 30);
// 检查person的constructor属性
console.log(person.constructor === Person); // 输出: true
console.log(person.constructor.name); // 输出: "Person"
Object.create(proto, [propertiesObject])
建一个新对象,使用现有的对象来提供新创建的对象的__proto__
。call, apply
改变this
指向,
call
和apply
的主要区别在于它们如何接收参数:
call
接受一个参数列表,而apply
接受一个参数数组。
这两个方法都允许你改变函数内部的this
上下文,这在处理回调函数、对象方法以及继承等场景中非常有用
// 1. call
function Car(age, sex){
this.name = '小刘',
this.age = age,
this.sex = sex
};
var obj = {};
Car.call(obj,112, '男'); // 将Car内this的指向指向 obj
// 2. apply
function Car(age, sex){
this.name = '小刘',
this.age = age,
this.sex = sex
};
var obj = {};
Car.apply(obj,[112, '女']);
继承
// 继承方法
var inherit = (function(){
var F = function (){}; // 闭包私有化变量,不属于对象,和对象同属于同一个AO对象
return function(Target,Origin){
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target;
Target.prototype.uber = Origin.prototype;
}
}());
function Car(name){
this.name = name
};
Car.prototype.whool = 4;
function BaoMa(){}
inherit(BaoMa,Car);
BaoMa.prototype.age = '百年历史';
var baoma = new BaoMa();
命名空间
// 1.
var obj = {
eat:{
li:{
name: '小李定义的eat'
},
zhang:{
name: '小张定义的eat'
}
},
drink:{
li:{
name:'小李定义的drink'
}
},
};
<!-- 调用 -->
var li = obj.eat.li;
li.name
// 2. 利用闭包实现,不污染全局变量
var name = '全局name变量';
var init = (function (){
var name = '函数内部name变量';
function say(){
console.log(name);
}
return function(){
say()
}
}());
对象枚举
for...in
语句用于遍历一个对象的可枚举属性(包括自有属性和继承自原型链的属性)。它会枚举对象的每一个可枚举属性,并为每个属性执行一次循环体。var obj = {
name:'小刘',
age: 18,
sex: 'male',
wife: '小宋',
__proto__:{
lastName:'Deng'
}
}
Object.prototype.abc = 123;
for(var prop in obj){
console.log(`${prop} -- ${obj[prop]}`)
}
hasOwnProperty
是一个方法,用于检查一个对象自身(不包括其原型链)是否具有指定的属性// 上例 obj
for(var prop in obj){
if(obj.hasOwnProperty(prop)){
console.log(`${prop} -- ${obj[prop]}`)
}
}
in
运算符用于检查对象自身及其原型链中是否存在某个属性。它会返回一个布尔值,如果对象或其原型链上有一个名为给定字符串的属性,则返回 true
;否则返回false
// 上例 obj
console.log('name' in obj) // true
console.log('abc' in obj) // true
instanceof
是一个运算符,用于测试构造函数的 prototype
属性是否出现在对象的原型链中的任何位置。换句话说,它用来判断一个对象是否是一个构造函数的实例// 区分数组[]和对象{}
// typeof([]); ---> object
// typeof({}); ---> object
var arr = [];
var obj = {};
// 1. instanceof 方法
arr instanceof Array; // true
obj instanceof Array; // false
arr instanceof Object; // true
obj instanceof Object; // true
// 2. constructor
arr.constructor // function Array
obj.constructor // function Object
// 3. call toString
Object.prototype.toString.call([]); // '[object Array]'
Object.prototype.toString.call({}); // '[object Object]'
this
this
指向window
this
指向window
call/apply
: 改变函数运行时 this
指向obj.func()
: func()
里的this
指向obj
(谁调用指向谁)arguments
函数实参的类数组对象(use strict
严格模式下禁用)arguments.length
对象长度arguments.callee
指向函数自身引用func.caller
函数的属性,函数被谁调用,返回谁// 'use strict' // 严格模式下禁用
var num = (function (n) {
if (n === 1) {
return 1
}
return n * arguments.callee(n - 1)
}(5))
num // 120
function demo() {
test();
}
function test() {
console.log(test.caller);
}
demo();