文章目录
前言
在 JS 中,字符串、数值、数组、函数都是对象。对个对象中包含若干个属性和方法。
一、创建对象
1、直接使用{ }创建对象
// JS 中的语句的结尾可以加分号(;),也可以不加分号(;),但是建议大家都加上分号
var a = {
}; // JS 中的空对象,类似 Java 中的空的 Map
var b = {
}
var student = {
// 使用 冒号(:) 分割 key 和 value
name: '小曹',
age: 18
};
console.log(a);
console.log(student);
function someMethod() {
console.log("去外婆家");
}
var person = {
name: '小红帽',
age: 8,
doing: someMethod, // 把已经定义的函数作为 doing key 的 value
say: function (target) {
// 把匿名函数作为 say key 的 value
console.log("你好, " + target);
}
};
console.log(a);
console.log(student);
console.log(person);
//或者也可以这样写
//console.log(person.name);
//console.log(person['name']);
//person.say();
//person['say']();
- 动态特性
// JS 中的对象,像 Map 一样是开放着的,可以随时随地的动态添加 key-value 进去
student.teacher = '小何';
student['master'] = '肖战';
console.log(student);
student['say'] = person.say;
student.say('世界');
2、当有多个对象时
方法一 ※推荐
function createStudent(name, age) {
var s = {
name: name,
age: age
};
s.sayHello = function (target) {
console.log("你好," + target);
};
return s;
}
var o1 = createStudent('张三', 13);
var o2 = createStudent('李四', 14);
方法二:构造函数
// JS 中本身是没有类的概念的,可以把(大写) Student 这个函数暂时当成类 + 构造方法去使用
// 构造函数的函数名首字母一般是大写的
function Student(name, age) {
// this 代表当前对象 :把整个函数当成构造函数
this.name = name;
this.age = age;
this.sayHello = function (target) {
console.log("Hello," + target);
};
// 不需要 return :理解 整个函数是构造函数,所以没有返回值
}
var o1 = new Student('王五', 15);
var o2 = new Student('赵六', 16);
注意 容易犯错误
方法三:语法糖形式
//在ES6中引入了class关键字,可以按照Java的方式来创建类和对象
//没有访问限定,认为都是 public 的
class Student {
// 由于 js 对象中的属性是开放的,可以随时随地添加,所以不规定属性
// constructor : 构造方法,无论 class 叫什么名字
constructor(name, age) {
this.name = name;
this.age = age;
}
// 规定:这里不用写 function 了
sayHello(target) {
console.log('你好 ' + target);
}
}
var o1 = new Student('钱七', 17);
this使用
- JS中的this比较复杂,目前可以把this当成当前对象使用。
- 具体内容可以浏览:https://juejin.im/post/5b8a48b6f265da432e75daae
class Student {
constructor(name, age) {
this['name'] = name; // 这种形式也可以
this.age = age; // this.age 当前对象中的 age
}
introduce() {
// 规定:必须是 this.name,不能省略 this,写成 name
console.log(this.name + ", " + this['age']);
}
}
var o1 = new Student('李一', 111);
o1.introduce();
二、JavaScript 的对象和 Java 的对象的区别
1、JS中没有“类”的概念
- 对象其实就是“属性” + “方法”(key-value)。Java中的对象是有限制的key-value,key一开始就定义类时就有规定有哪些类,类型也是确定的。
- 类相当于把一些具有共性的对象的属性和方法单独提取了出来, 相当于一个 “月饼模子”。
- 在 JavaScript 中的 “构造函数” 也能起到类似的效果.。而且即使不是用构造函数, 也可以随时的通过 { } 的方式指定出一些对象。
2、JS对象不区分“属性”和“方法”
- JavaScript 中的函数是 “一等公民”, 和普通的变量一样. 存储了函数的变量能够通过 ( ) 来进行调用执行。
3、JS对象没有private/public等访问控制机制
- JS中的对象全部都是public的。
4、JS对象没有“继承”
- 继承本质就是 “让两个对象建立关联”. 或者说是让一个对象能够重用另一个对象的属性/方法.。JavaScript 中使用 “原型” 机制实现类似的效果。
原型链(prototype chains)
- 例如之前显示的
5. JavaScript 没有 “多态”
-
面向对象的三大原则:
- 封装:有封装,比较粗浅,是非常初步的封装。
- 继承:使用原型链的方式。
- 多态:JS由于无类型限制,天生就是多态的。
-
Java 等静态类型的语言对于类型的约束和校验比较严格。因此通过 子类继承父类, 并重写父类的方法的方式 来实现多态的效果。
-
在JS中本身就支持动态类型, 在使用对象的某个方法的时候本身也不需要对 对象的类型 做出明确区分。因此并不需要在语法层面上支持多态。
举例
- 习惯上,称这种方式叫做鸭子类型(duck type)。在处理一个对象时,不用管是不是鸭子,只要符合特征(毛是黄色的,叫声是“嘎嘎嘎”,有翅膀)就是我们要的对象。
function f(o) {
o.say();
}
f({
say: function () {
console.log('我是临时构造的对象')}
});
function f(o) {
// 根本不管 o 是什么类型,只要求: o 这个对象有 key 是 say 的 value
// 并且 value 的值是 function
o.say();
}
function Student() {
this.say = function() {
console.log('我是学生'); }
}
var o = new Student();
f(o);