js_面向对象_new关键字_对象与this_ES6种对象相关的特性实例
文章目录
字面量对象
重新介绍 JavaScript(JS 教程) - JavaScript | MDN (mozilla.org)
- 对象作为函数参数:
在经典的面向对象语言中,对象是指数据和在这些数据上进行的操作的集合。与 C++ 和 Java 不同,JavaScript 是一种基于原型的编程语言,并没有 class 语句,而是把函数用作类。那么让我们来定义一个人名对象,这个对象包括人的姓和名两个域(field)。名字的表示有两种方法:“名 姓(First Last)”或“姓, 名(Last, First)”。使用我们前面讨论过的函数和对象概念,可以像这样完成定义:
function makePerson(first, last) {
return {
first: first,
last: last
};
}
function personFullName(person) {
return person.first + ' ' + person.last;
}
function personFullNameReversed(person) {
return person.last + ', ' + person.first;
}
var s = makePerson('Simon', 'Willison');
personFullName(s); // "Simon Willison"
personFullNameReversed(s); // "Willison, Simon"
利用返回对象的函数创建对象
function makePerson(first, last) {
return {
first: first,
last: last
};
}
利用关键字new调用构造函数(constructor)来得到(或者说constructor修改一个空对象)得到想要的对象
利用原型链修改对象模板中的属性/方法
function Person(first, last) {
this.first = first;
this.last = last;
}
Person.prototype.fullName = function() {
return this.first + ' ' + this.last;
}
Person.prototype.fullNameReversed = function() {
return this.last + ', ' + this.first;
}
原型对象
Person.prototype 是一个可以被 Person的所有实例共享的对象。
它是一个名叫 原型链(prototype chain)的 查询链的一部分:当你试图访问 Person<span>某个实例(例如上个例子中的s)一个没有定义的属性时,解释器会首先检查这个 Person.prototype来判断是否存在这样一个属性。
所以,任何分配给 Person.prototype的东西对通过 this 对象构造的实例都是可用的。
这个特性功能十分强大,JavaScript 允许你在程序中的任何时候修改原型(prototype)中的一些东西,也就是说你可以在运行时(runtime)给已存在的对象添加额外的方法:
s = new Person("Simon", "Willison");
s.firstNameCaps(); // TypeError on line 1: s.firstNameCaps is not a function
Person.prototype.firstNameCaps = function() {
return this.first.toUpperCase()
}
s.firstNameCaps(); // SIMON
new与构造函数(结合this)
实现一个和 new关键字有类似效果的 trivial方法:
- 下面是一个
new方法的简单实现:
function trivialNew(constructor, ...args) {
var o = {}; // 创建一个对象
constructor.apply(o, args);
return o;
}
note:
这并不是 new 的完整实现,因为它没有创建原型(prototype)链。
(想举例说明 new 的实现有些困难)l因为你不会经常用到这个,但是适当了解一下还是很有用的。
在这一小段代码里,...args(包括省略号)叫作剩余参数(rest arguments)。如名所示,这个东西包含了剩下的参数。
因此,调用
var bill = trivialNew(Person, "William", "Orange");
可认为和调用如下语句是等效的
var bill = new Person("William", "Orange");
this
关键字 this。当使用在函数中时,this 指代当前的对象,也就是 调用了函数的对象。
如果在一个对象上使用 点或者方括号来访问属性或方法,这个对象就成了 this。
否则, this 将指向全局对象(global object)。这是一个经常出错的地方。
使用关键字 this 改进已有的 makePerson函数:
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = function() {
return this.first + ' ' + this.last;
}
this.fullNameReversed = function() {
return this.last + ', ' + this.first;
}
}
var s = new Person("Simon", "Willison");
我们引入了另外一个关键字:new,它和 this 密切相关。
它(new)的作用是创建一个崭新的 空对象{},然后使用指向那个对象的 this调用特定的函数。
注意,含有 this的特定函数不会返回任何值,只会修改 this 对象本身。
new关键字将生成的 this对象返回给调用方,而被 new调用的函数称为构造函数。(是的,只是某个函数被new调用了,那么被调用的函数就叫构造函数;但是一般的,我们会让new调用一个适合用来创建的对象的函数,习惯上,这样的被设计为初始化对象的函数首字母大写,这样用new 调用他们的时候就容易识别了)
指定this(对象)来调用基于该this对象的面向对象的方法
- 用对象
obj.FunctionName()或obj[FunctionName]()的行形式调用,方法中的this指的就是obj - 用函数对象的
apply():FunctionName.apply(thisArg,argArray)
- 用函数对象的
call():FunctionName.call(thisArg,argList)
call()
知道了 new和 this的基本特点和工作原理后,我们看一下 call()是
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
console.log(new Food('cheese', 5));//Food { name: 'cheese', price: 5, category: 'food' }
console.log(new Food('cheese', 5).name);// expected output: "cheese"
console.log((new Food('cheese', 5)).name);//the same as `new Food('cheese',5).name`
console.log(Food('cheese', 5));//expected undefined
// console.log(new (Food('cheese',5).name));// Wrong! TypeError
// console.log(Food('Cheese',5).name);//Wrong! TypeError
console.log();
这里,
<strong>call()</strong>方法使用 一个指定的 this 值和 单独给出的一个或多个参数来 调用一个函数。
注意: 该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表 ,而 apply() 方法接受的是一个包含多个参数的数组 。
对于本例代码,的new调用处,创建了一个空对象,然后用该空对象的this去调用函数Food(),Food()将会对这个空对象进行处理,Food()内部调用了Product函数对象的call()方法,该方法将空对象作为this实参,后面的name,price参数列表将传递给Product()函数,这样函数Product所作用于的对象this就是new出来的空对象的this.
new还将生成的this对象返回给调用方(本例的测试中对这个new 所调用的构造函数修饰后的this对象调用(访问)了其name属性.
new 小结
总之,new 是基于新建一个空对象 {}的基础上执行一些操作
apply()
call()中的例子用apply()来改写:
function Food(name, price) {
Product.apply(this, [name, price]);
this.category = 'food';
}
ES6种对象相关的特性
obj = {
d: console.log,
name: "NameInObj",
data: {
name: "nameIndataOfobj",
age: 18
},
methodInObj: function () {
console.log(this.data.name);
console.log(this.data.age);
this.d(this.data);
// console.log(name);
},
/* 定义函数的若干种方式: */
m1: function () {
console.log("I am the method1😎");
},
/* 简化写法m1:将`:function`省略掉 */
m2() {
console.log("I am the method2❤️");
}
,
/* 测试箭头函数的对象绑定特性 */
testThis() {
const that = this;
setTimeout(
function () {
console.log(this.name + " 😎test this within setTimeOut(expected undefined)");
}
);
setTimeout(
function () {
console.log(that.name + " 😎test this within setTimeOut(expected name in obj)");
}
);
setTimeout(() => {
console.log(this.name + ` 👌test that within settimeOut(expected name in obj) `);
}, 0);
}
};
function testmethod() {
obj.methodInObj;
obj.methodInObj();
console.log(obj.methods);
}
// console.log(obj.methods());
// console.log(obj);
function testMn() {
obj.m1();
obj.m2();
}
// testMn()
obj.testThis();

浙公网安备 33010602011771号