Js表达式和运算符

2018.10.12 星期五 17:15

new操作符的工作原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var F=function(){
//this指向谁,在定义时是不知道的
};

var p=new F; // $有无 () 都可以调用,有参和无参,和. 运算优先级不一样
// ## 1 代码说明
var o = new Object();
o.__proto__ = Foo.prototype;
Foo.call(o);
// return *.

// ## 2.1 封装函数
function Person (name) {
this.name = name;
}
function newFunc (name) {
var o = {};
o.__proto__ = Person.prototype;//绑定Person的原型
Person.call(o, name);
return o;
};
var person1=newFunc('person1')
person1.name//
person1 instanceof Person // false 不绑定Person的原型 ;绑定返回true

// ## 2.2 扩展assign
// 如果再将这个函数抽象一下,可以传入构造函数:
function newFunc(constructor){
var o = {};
o.__proto__ = constructor.prototype;
constructor.apply(o, Array.prototype.slice.call(arguments, 1));
return o;
}
var person1 = newFunc(Person, 'MeloGuo', 21)

用new调用一个函数发生了这些事:
(1)新建一个对象instance=new Object();
(2)设置原型链instance.__proto__=F.prototype;
(3)让F中的this指向instance,执行F的函数体。
(4)判断F的返回值类型:
如果是值类型,就丢弃它,还是返回instance。
如果是引用类型,就返回这个引用类型的对象,替换掉instance。

注:(1)如果没有写return,相当于return undefined,JavaScript中的函数都是这样。undefined是值类型的,因此丢弃它,返回instance。
(2)如果return this相当于返回一个引用类型的对象,它自己就是instance,无所谓替换不替换了。
(3)对instance并不需要设置它的constructor属性,这个属性在instance的原型中。
而且,任意一个新函数在创建时,原型的constructor就已经设置好了。
于是,这也要求我们在对prototype重新赋值的时候,重新指定constructor属性。

1
2
3
4
5
6
7
8
9
10
console.assert(!p.hasOwnProperty('constructor'));
console.assert(F.prototype.hasOwnProperty('constructor'));
// 而且 。。
var G=function(){};
console.assert(G.prototype.hasOwnProperty('constructor'));
console.assert(G.prototype.constructor===G);
// 重新指定constructor属性。
F.prototype={
constructor:F
};

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function New(f) {
//返回一个func
return function () {
var o = {"__proto__": f.prototype};
f.apply(o, arguments);//继承父类的属性
return o; //返回一个Object
}
}
function Person(name,age){
this.name = name;
this.age = age;
}
var p2 = New(Person)("Jack",25);
p2.name;//Jack
p2.age;//25
p2 instanceof Person // true
Person.prototype.gender ="male";
p2.gender//male

练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// new 、this、以及原型链相关问
function Foo(){
getName = function(){
console.log(1)
}
console.log(this)
return this;
}
Foo.getName = function(){
console.log(2)
}
Foo.prototype.getName = function(){
console.log(3)
}
var getName = function(){
console.log(4)
}
function getName(){
console.log(5)
}
Foo.getName(); // 2 // Foo的静态方法(如果C#、java等后端语言来说)
getName(); // 4
Foo().getName(); // 1 // $PS:3,没有new即也就不会返回实例,return的this指window
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3 // 有new 返回实例;
// 由于new是有参的,与.运算符同级,按照从左向右的执行顺序,先执行new Foo()。
new new Foo().getName(); // 3
// 原理:主要是运算符优先级的考查,实例开发中应该不会这样直接的用到。首先new有参,然后.getName(.运算符)(为什么是.运算符,这是因为new无参级别低一个档次),再则new有参。


/* $PS: function的声明在var 前面
console.log(name) // f name(){}
var name;
function name(){} */

Object()和new Object()

当以非构造函数形式被调用时,Object 等同于 new Object()

与.运算优先级比较

new是有参的,与.运算符同级,按照从左向右的执行顺序,先执行new Foo()
new无参级别低一个档次,先进行.运算符

18:55

knowledge is no pay,reward is kindness
0%