一.创建对象
<body>
<script>
// 1.字面量创建
var obj = {
name: "小好",
gender: "男",
age: 18,
sayHi: function () {
console.log("hello");
}
}
// 2.构造函数
function Person(name, age, gender, sayHi) {
this.name = name;
this.age = age;
this.gender = gender;
this.sayHi = sayHi;
}
// 实例化
function sayHi() {
console.log("你好");
}
var person = new Person("小谷", 20, "女", sayHi);
console.log(person);
// 3.new Object() 构造器
var obj2 = new Object();
obj2.name = "zhangsan";
obj2.age = 21;
obj2.gender = "男";
obj2.sayHi = function () {
console.log("扣你吉瓦");
}
// 遍历对象
for (var key in obj) {
console.log(key);
console.log(obj[key]);
}
// Object.keys(obj)
// 该方法会返回一个由一个给定对象的自身可枚举属性组成的数组
console.log(Object.keys(obj));
// Object.getOwnPropertyNames(obj)
// 该方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
console.log(Object.getOwnPropertyNames(obj));
// 检查是否拥有该属性
console.log("hobby" in obj);
// 删除属性
obj.name = "";
obj.age = null;
delete obj.gender;
console.log(obj);
</script>
</body>
</html>
二.属性特征
<body>
<script>
// 1.字面量创建
var obj = {
// 数据属性
name: "小好",
gender: "男",
age: 18,
sayHi: function () {
console.log("hello");
},
// 访问器属性
get newName() {
console.log("访问了newName");
return "xxx";
},
set setName(value) {
console.log("设置了setName");
this.name = value;
}
}
console.log(obj);
console.log(obj.newName);
obj.setName = "小谷";
</script>
</body>
</html>
三.定义属性
<body>
<script>
// 通过赋值操作定义对象,添加的普通属性,**注意**:默认情况下都是可修改、可枚举、可配置(删除或添加)的。
var obj = {
name: "小好"
}
// Object.defineProperty(obj, prop, descriptor);
// 方法接受3个参数:拥有被修改属性的对象、被修改的属性名、包含描述特征的对象
Object.defineProperty(obj, "age", {
// 是否可配置
configurable: false,
// 是否可枚举
enumerable: false,
// 是否可修改
writable: true,
// 值
value: 18
})
console.log(obj);
// 遍历对象
for (var key in obj) {
console.log(key);
}
console.log(Object.keys(obj));
console.log(Object.getOwnPropertyNames(obj));
obj.age = 20;
console.log(obj);
delete obj.age;
console.log(obj);
</script>
</body>
</html>
四.定义多个属性
<body>
<script>
var obj = {
name: "小好"
}
// 定义多个属性
Object.defineProperties(obj, {
age: {
// 是否可配置
configurable: false,
// 是否可枚举
enumerable: false,
// 是否可修改
writable: true,
// 值
value: 18
},
gender: {
// 是否可配置
configurable: false,
// 是否可枚举
enumerable: false,
// 是否可修改
writable: true,
// 值
value: "男"
}
})
console.log(obj);
</script>
</body>
</html>
五.获取属性特征
<body>
<script>
var obj = {
name: "小好"
}
// 定义多个属性
Object.defineProperties(obj, {
age: {
// 是否可配置
configurable: false,
// 是否可枚举
enumerable: false,
// 是否可修改
writable: true,
// 值
value: 18
},
gender: {
// 是否可配置
configurable: true,
// 是否可枚举
enumerable: false,
// 是否可修改
writable: true,
// 值
value: "男"
}
})
console.log(obj);
// 查看属性的特征
console.log(Object.getOwnPropertyDescriptor(obj, "age"));
console.log(Object.getOwnPropertyDescriptor(obj, "gender"));
// 查看所有属性特征
console.log(Object.getOwnPropertyDescriptors(obj));
</script>
</body>
</html>
六.构造函数
<body>
<script>
// 构造函数
function Person(name, age, gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
// 普通函数
function sum(a, b) {
return a + b;
}
// 构造函数和普通函数的区别
// 构造函数
// 1.首字母大写
// 2.this 指向实例化对象
// 3.构造函数不需要 return
// 普通函数
// 1.this 指向 window
// 2.不需要使用 new 关键字
// 3.有 return
</script>
</body>
</html>
七.静态成员和实例成员
<body>
<script>
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
}
// 给构造函数本身添加静态成员
Person.hobby = "敲代码";
// 实例化对象
var person = new Person("小好", 18, "男");
console.log(person);
console.log(person.name); // 实例化对象只能访问实例成员
console.log(person.hobby); // 不能访问静态成员
// 实例化对象
var person2 = new Person("小谷", 20, "女");
console.log(person2);
console.log(Person.hobby); // 构造函数只能访问静态成员
console.log(Person.name); // 不能访问实例成员
</script>
</body>
</html>
八.构造函数的原型
<body>
<script>
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
// this.skill = function () {
// console.log("敲代码");
// }
}
// 每一个构造函数都有一个prototype 属性,其属性值为对象,称为原型对象。
// 原型对象的作用: 共享属性和方法,节约内存
// 给原型对象上创建属性和方法
Person.prototype.skill = function () {
console.log("敲代码");
}
Person.prototype.money = "10k+";
// 实例化对象
var stu1 = new Person("田鹏鹏", 22, "男");
console.log(stu1);
stu1.skill();
console.log(stu1.money);
var stu2 = new Person("李雨飞", 20, "男");
console.log(stu2);
stu2.skill();
console.log(stu2.money);
</script>
</body>
</html>
九.对象原型
<body>
<script>
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.skill = function () {
console.log("敲代码");
}
var person1 = new Person("小好", 20, "男");
// 每一个对象都会有一个属性 __proto__ 指向构造函数的 prototype 原型对象,之所以实例化对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__ 原型的存在。
// __proto__对象原型和原型对象 prototype 是等价的。
// __proto__对象原型的意义就在于为对象的查找机制提供一个方向,或者说一条路线,但是它是一个非标准属性,因此实际开发中,不可以使用这个属性,它只是内部指向原型对象prototype。
console.log(person1); // __proto__ 现在浏览器显示为 [[Prototype]]
console.log(Person.prototype);
console.log(person1.__proto__ === Person.prototype);
person1.__proto__.skill();
person1.skill();
</script>
</body>
</html>
十.constructor构造函数
<body>
<script>
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.skill = function () {
console.log("敲代码");
}
var person1 = new Person("小好", 20, "男");
console.log(person1);
</script>
</body>
</html>
十一.原型链
<body>
<script>
// 原型链
// 当访问一个对象的某个属性或方法时,会先在这个对象本身属性上查找,如果没有找到,则会去它的`__proto__`上查找,即它的构造函数的prototype,
// 如果还没有找到就会再在构造函数的prototype的`__proto__`中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
// (补充:直到找到顶层 Object, 如果还没有找到则返回null, 打印undefined)
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
// this.skill = function () {
// console.log("我自己会敲代码");
// }
}
// Person.prototype.skill = function () {
// console.log("敲代码");
// }
Object.prototype.hobby = "唱";
var person1 = new Person("小好", 20, "男");
console.log(person1);
console.log(person1.hobby);
</script>
</body>
</html>
十二.hasOwnProperty
<body>
<script>
var obj = {
name: "zhangsan"
}
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
this.skill = function () {
console.log("我自己会敲代码");
}
}
// Person.prototype.skill = function () {
// console.log("敲代码");
// }
// Object.prototype.hobby = "唱";
var person1 = new Person("小好", 20, "男");
// 可以判断一个属性定义在对象本身而不是继承原型链的方法,主要用于判断某个对象中是否有某个属性,返回值为布尔值。
console.log(Person.prototype.hasOwnProperty("skill"));
// isPrototypeOf方法接收一个对象,用来判断当前对象是否在传入的参数对象的原型链上,返回一个布尔值。
console.log(Person.prototype.isPrototypeOf(obj));
</script>
</body>
</html>
十三.扩展数组的方法
<body>
<script>
var arr = [1, 2, 3, 4, 5];
var arr1 = new Array(1, 2, 3, 4, 5);
console.log(arr1);
// function sumFun(arr) {
// var sum = 0;
// for (var i = 0; i < arr.length; i++) {
// sum += arr[i];
// }
// return sum;
// }
Array.prototype.sumFun = function () {
var sum = 0;
for (var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
// this指向
console.log(arr1.sumFun());
</script>
</body>
</html>
十四.原型对象中的this指向
<body>
<script>
// 构造函数
function Person(name, age, gender) {
// 实例成员
this.name = name;
this.age = age;
this.gender = gender;
}
Person.prototype.skill = function () {
console.log("敲代码");
console.log(this);
}
var person1 = new Person("小好", 20, "男");
console.log(person1);
person1.skill();
// 原型对象中 this 指向实例化对象
</script>
</body>
</html>