window.foo = 123
function print() {
this.foo = 234;
console.log(this);
console.log(window.foo);
}
window.print()
题目1.2:严格模式
把 题目1.1
稍作修改,看看严格模式下的执行结果。
"use strict"
可以开启严格模式
“use strict”;
var foo = 123;
function print(){
console.log('print this is ', this);
console.log(window.foo)
console.log(this.foo);
}
console.log('global this is ', this);
print();
注意事项:开启严格模式后,函数内部 this
指向 undefined
,但全局对象 window
不会受影响
答案
global this is Window{…}
print this is undefined
123
Uncaught TypeError: Cannot read property ‘foo’ of undefined
题目1.3:let/const
let a = 1;
const b = 2;
var c = 3;
function print() {
console.log(this.a);
console.log(this.b);
console.log(this.c);
}
print();
console.log(this.a);
let/const
定义的变量存在暂时性死区,而且不会挂载到 window
对象上,因此 print
中是无法获取到 a和b
的。
答案
undefined
undefined
3
undefined
题目1.4:对象内执行
a = 1;
function foo() {
console.log(this.a);
}
const obj = {
a: 10,
bar() {
foo(); // 1
}
}
obj.bar();
foo
虽然在 obj
的 bar
函数中,但 foo
函数仍然是独立运行的, foo
中的 this
依旧指向 window
对象。
题目1.5:函数内执行
var a = 1
function outer () {
var a = 2
function inner () {
console.log(this.a) // 1
}
inner()
}
outer()
这个题与 题目1.4
类似,但要注意,不要把它看成闭包问题
题目1.6:自执行函数
a = 1;
(function(){
console.log(this);
console.log(this.a)
}())
function bar() {
b = 2;
(function(){
console.log(this);
console.log(this.b)
}())
}
bar();
默认情况下,自执行函数的 this
指向 window
自执行函数只要执行到就会运行,并且只会运行一次, this
指向 window
。
答案
Window{…}
1
Window{…}
2 // b是imply global,会挂载到window上
2.隐式绑定
函数的调用是在某个对象上触发的,即调用位置存在上下文对象,通俗点说就是**XXX.func()**这种调用模式。
此时 func
的 this
指向 XXX
,但如果存在链式调用,例如 XXX.YYY.ZZZ.func
,记住一个原则: this永远指向最后调用它的那个对象 。
题目2.1:隐式绑定
var a = 1;
function foo() {
console.log(this.a);
}
// 对象简写,等同于 {a:2, foo: foo}
var obj = {a: 2, foo}
foo();
obj.foo();
-
foo()
: 默认绑定,打印1
-
obj.foo()
: 隐式绑定,打印2
答案
obj
是通过 var
定义的, obj
会挂载到 window
之上的, obj.foo()
就相当于 window.obj.foo()
,这也印证了 this永远指向最后调用它的那个对象 规则。
题目2.2:对象链式调用
感觉上面总是空谈链式调用的情况,下面直接来看一个例题:
var obj1 = {
a: 1,
obj2: {
a: 2,
foo(){
console.log(this.a)
}
}
}
obj1.obj2.foo() // 2
3.隐式绑定的丢失
隐式绑定可是个调皮的东西,一不小心它就会发生绑定的丢失。一般会有两种常见的丢失:
-
使用另一个变量作为函数别名,之后使用别名执行函数
-
将函数作为参数传递时会被隐式赋值
隐式绑定丢失之后, this
的指向会启用默认绑定。
具体来看题目:
题目3.1:取函数别名
a = 1
var obj = {
a: 2,
foo() {
console.log(this.a)
}
}
var foo = obj.foo;
obj.foo();
foo();
JavaScript
对于引用类型,其地址指针存放在栈内存中,真正的本体是存放在堆内存中的。
上面将 obj.foo
赋值给 foo
,就是将 foo
也指向了 obj.foo
所指向的堆内存,此后再执行 foo
,相当于直接执行的堆内存的函数,与 obj
无关, foo
为默认绑定。笼统的记, 只要fn前面什么都没有,肯定不是隐式绑定 。
答案
不要把这里理解成 window.foo
执行,如果 foo
为 let/const
定义, foo
不会挂载到 window
上,但不会影响最后的打印结果
题目3.2:取函数别名
如果取函数别名没有发生在全局,而是发生在对象之中,又会是怎样的结果呢?
var obj = {
a: 1,
foo() {
console.log(this.a)
}
};
var a = 2;
var foo = obj.foo;
var obj2 = { a: 3, foo: obj.foo }
obj.foo();
foo();
obj2.foo();
obj2.foo
指向了 obj.foo
的堆内存,此后执行与 obj
无关(除非使用 call/apply
改变 this
指向)
答案
题目3.3:函数作为参数传递
function foo() {
console.log(this.a)
}
function doFoo(fn) {
console.log(this)
fn()
}
var obj = { a: 1, foo }
var a = 2
doFoo(obj.foo)
用函数预编译的知识来解答这个问题:函数预编译四部曲前两步分别是:
-
找形参和变量声明,值赋予
undefined
-
将形参与实参相统一,也就是将实参的值赋予形参。
obj.foo
作为实参,在预编译时将其值赋值给形参 fn
,是将 obj.foo
指向的地址赋给了 fn
,此后 fn
执行不会与 obj
产生任何关系。 fn
为默认绑定。
答案
Window {…}
2
题目3.4:函数作为参数传递
将上面的题略作修改, doFoo
不在 window
上执行,改为在 obj2
中执行
function foo() {
console.log(this.a)
}
function doFoo(fn) {
console.log(this)
fn()
}
var obj = { a: 1, foo }
var a = 2
var obj2 = { a: 3, doFoo }
obj2.doFoo(obj.foo)
console.log(this)
obj2.doFoo
xxx.fn
doFoo
this
obj2
{a: 3, doFoo: ƒ}
fn()
: 没有于obj2
产生联系,默认绑定,打印2
答案
{a: 3, doFoo: ƒ}
2
题目3.5:回调函数
下面这个题目我们写代码时会经常遇到:
var name=‘zcxiaobao’;
function introduce(){
console.log('Hello,My name is ', this.name);
}
const Tom = {
name: ‘TOM’,
introduce: function(){
setTimeout(function(){
console.log(this)
console.log('Hello, My name is ',this.name);
})
}
}
const Mary = {
name: ‘Mary’,
introduce
}
const Lisa = {
name: ‘Lisa’,
introduce
}
Tom.introduce();
setTimeout(Mary.introduce, 100);
setTimeout(function(){
Lisa.introduce();
},200);
setTimeout
是异步调用的,只有当满足条件并且同步代码执行完毕后,才会执行它的回调函数。
Tom.introduce()执行
console
setTimeout
this
window
Mary.introduce
setTimeout
题目3.3
this
Lisa.introduce
setTimeout
xxx.fn
this
答案
Window {…}
Hello, My name is zcxiaobao
Hello,My name is zcxiaobao
Hello,My name is Lisa
所以如果我们想在 setTimeout
或 setInterval
中使用外界的 this
,需要提前存储一下,避免 this
的丢失。
const Tom = {
name: ‘TOM’,
introduce: function(){
_self = this
setTimeout(function(){
console.log('Hello, My name is ',_self.name);
})
}
}
Tom.introduce()
题目3.6:隐式绑定丢失综合题
name = ‘javascript’ ;
let obj = {
name: ‘obj’,
A (){
this.name += ‘this’;
console.log(this.name)
},
B(f){
this.name += ‘this’;
f();
},
C(){
setTimeout(function(){
console.log(this.name);
},1000);
}
}
let a = obj.A;
a();
obj.B(function(){
console.log(this.name);
});
obj.C();
console.log(name);
本题目不做解析,具体可以参照上面的题目。
答案
javascriptthis
javascriptthis
javascriptthis
undefined
4.显式绑定
显式绑定比较好理解,就是通过 call()、apply()、bind()
等方法,强行改变 this
指向。
上面的方法虽然都可以改变 this
指向,但使用起来略有差别:
-
call()和apply()
函数会立即执行 -
bind()
函数会返回新函数,不会立即执行函数
call()和apply()
call
apply
题目4.1:比较三种调用方式
function foo () {
console.log(this.a)
}
var obj = { a: 1 }
var a = 2
foo()
foo.call(obj)
foo.apply(obj)
foo.bind(obj)
foo()
: 默认绑定。
foo.call(obj)
foo
this
obj
-
foo.apply(obj)
: 显式绑定 -
foo.bind(obj)
: 显式绑定,但不会立即执行函数,没有返回值
答案
题目4.2:隐式绑定丢失
题目3.4
发生隐式绑定的丢失,如下代码:我们可不可以通过显式绑定来修正这个问题。
function foo() {
console.log(this.a)
}
function doFoo(fn) {
console.log(this)
fn()
}
var obj = { a: 1, foo }
var a = 2
doFoo(obj.foo)
- 首先先修正
doFoo()
函数的this
指向。
doFoo.call(obj, obj.foo)
- 然后修正
fn
的this
。
function foo() {
console.log(this.a)
}
function doFoo(fn) {
console.log(this)
fn.call(this)
}
var obj = { a: 1, foo }
var a = 2
doFoo(obj.foo)
大功告成。
题目4.3:回调函数与call
接着上一个题目的风格,稍微变点花样:
var obj1 = {
a: 1
}
var obj2 = {
a: 2,
bar: function () {
console.log(this.a)
},
foo: function () {
setTimeout(function () {
console.log(this)
console.log(this.a)
}.call(obj1), 0)
}
}
var a = 3
obj2.bar()
obj2.foo()
乍一看上去,这个题看起来有些莫名其妙, setTimeout
那是传了个什么东西?
做题之前,先了解一下 setTimeout
的内部机制:(关于异步的执行顺序,可以参考 JavaScript之EventLoop [6] )
setTimeout(fn) {
if (回调条件满足) (
fn
)
}
这样一看,本题就清楚多了,类似 题目4.2
,修正了回调函数内 fn
的 this
指向。
答案
2
{a: 1}
1
题目4.4:注意call位置
function foo () {
console.log(this.a)
}
var obj = { a: 1 }
var a = 2
foo()
foo.call(obj)
foo().call(obj)
-
foo()
: 默认绑定 -
foo.call(obj)
: 显式绑定
foo().call(obj)
foo()
call
foo
undefined
call()
答案
2
1
2
Uncaught TypeError: Cannot read property ‘call’ of undefined
题目4.5:注意call位置(2)
上面由于 foo
没有返回函数,无法执行 call
函数报错,因此修改一下 foo
函数,让它返回一个函数。
function foo () {
console.log(this.a)
return function() {
console.log(this.a)
}
}
var obj = { a: 1 }
var a = 2
foo()
foo.call(obj)
foo().call(obj)
-
foo()
: 默认绑定 -
foo.call(obj)
: 显式绑定
foo().call(obj)
foo()
2
call
this
obj
1
这里千万注意:最后一个 foo().call(obj)
有两个函数执行,会打印 2个值 。
答案
题目4.6:bind
将上面的 call
全部换做 bind
函数,又会怎样那?
call是会立即执行函数,bind会返回一个新函数,但不会执行函数
function foo () {
console.log(this.a)
return function() {
console.log(this.a)
}
}
var obj = { a: 1 }
var a = 2
foo()
foo.bind(obj)
foo().bind(obj)
首先我们要先确定,最后会输出几个值? bind
不会执行函数,因此只有两个 foo()
会打印 a
。
-
foo()
: 默认绑定,打印2
-
foo.bind(obj)
: 返回新函数,不会执行函数,无输出
foo().bind(obj)
foo()
2
bind
foo()
this
obj
答案
题目4.7:外层this与内层this
做到这里,不由产生了一些疑问:如果使用 call、bind
等修改了外层函数的 this
,那内层函数的 this
会受影响吗?(注意区别箭头函数)
function foo () {
console.log(this.a)
return function() {
console.log(this.a)
}
}
var obj = { a: 1 }
var a = 2
foo.call(obj)()
foo.call(obj)
: 第一层函数 foo
通过 call
将 this
指向 obj
,打印 1
;第二层函数为匿名函数,默认绑定,打印 2
。
答案
题目4.8:对象中的call
把上面的代码移植到对象中,看看会发生怎样的变化?
var obj = {
a: ‘obj’,
foo: function () {
console.log(‘foo:’, this.a)
return function () {
console.log(‘inner:’, this.a)
}
}
}
var a = ‘window’
var obj2 = { a: ‘obj2’ }
obj.foo()()
obj.foo.call(obj2)()
obj.foo().call(obj2)
看着这么多括号,是不是感觉有几分头大。没事,咱们来一层一层分析:
obj.foo()()
obj.foo()
foo:obj
inner:window
obj.foo.call(obj2)()
题目4.7
obj.foo.call(obj2)
call
obj.foo
this
obj2
foo: obj2
inner:window
obj.foo().call(obj2)
题目4.5
foo: obj
call
this
obj2
inner: obj2
题目4.9:带参数的call
显式绑定一开始讲的时候,就谈过 call/apply
存在传参差异,那咱们就来传一下参数,看看传完参数的this会是怎样的美妙。
var obj = {
a: 1,
foo: function (b) {
b = b || this.a
return function © {
console.log(this.a + b + c)
}
}
}
var a = 2
var obj2 = { a: 3 }
obj.foo(a).call(obj2, 1)
obj.foo.call(obj2)(1)
要注意 call
执行的位置:
-
obj.foo(a).call(obj2, 1)
: -
obj.foo(a)
: foo的AO中b值为传入的a(形参与实参相统一),值为2,返回匿名函数fn -
匿名函数
fn.call(obj2, 1)
: fn的this指向为obj2,c值为1 -
this.a + b + c = obj2.a + FooAO.b + c = 3 + 2 + 1 = 6
-
obj.foo.call(obj2)(1)
: -
obj.foo.call(obj2)
: obj.foo的this指向obj2,未传入参数,b = this.a = obj2.a = 3;返回匿名函数fn -
匿名函数
fn(1)
: c = 1,默认绑定,this指向window -
this.a + b + c = window.a + obj2.a + c = 2 + 3 + 1 = 6
答案
麻了吗,兄弟们。进度已经快过半了,休息一会,争取把 this
一次性吃透。
5.显式绑定扩展
上面提了很多 call/apply
可以改变 this
指向,但都没有太多实用性。下面来一起学几个常用的 call与apply
使用。
题目5.1:apply求数组最值
JavaScript中没有给数组提供类似max和min函数,只提供了 Math.max/min
,用于求多个数的最值,所以可以借助apply方法,直接传递数组给 Math.max/min
const arr = [1,10,11,33,4,52,17]
Math.max.apply(Math, arr)
Math.min.apply(Math, arr)
题目5.2:类数组转为数组
ES6
未发布之前,没有 Array.from
方法可以将类数组转为数组,采用 Array.prototype.slice.call(arguments)
或 [].slice.call(arguments)
将类数组转化为数组。
题目5.3:数组高阶函数
日常编码中,我们会经常用到 forEach、map
等,但这些数组高阶方法,它们还有第二个参数 thisArg
,每一个回调函数都是显式绑定在 thisArg
上的。
例如下面这个例子
const obj = {a: 10}
const arr = [1, 2, 3, 4]
arr.forEach(function (val, key){
console.log(${key}: ${val} --- ${this.a}
)
}, obj)
答案
0: 1 — 10
1: 2 — 10
2: 3 — 10
3: 4 — 10
关于数组高阶函数的知识可以参考: JavaScript之手撕高阶数组函数
6.new绑定
使用 new
来构建函数,会执行如下四部操作:
-
创建一个空的简单
JavaScript
对象(即{}
); -
为步骤1新创建的对象添加属性
__proto__
,将该属性链接至构造函数的原型对象 ; -
将步骤1新创建的对象作为
this
的上下文 ; -
如果该函数没有返回对象,则返回
this
。
关于new更详细的知识,可以参考: JavaScript之手撕new [7]
通过new来调用构造函数,会生成一个新对象,并且把这个新对象绑定为调用函数的this。
题目6.1:new绑定
function User(name, age) {
this.name = name;
this.age = age;
}
var name = ‘Tom’;
var age = 18;
var zc = new User(‘zc’, 24);
console.log(zc.name)
答案
zc
题目6.2:属性加方法
function User (name, age) {
this.name = name;
this.age = age;
this.introduce = function () {
console.log(this.name)
}
this.howOld = function () {
return function () {
console.log(this.age)
}
}
}
var name = ‘Tom’;
var age = 18;
var zc = new User(‘zc’, 24)
zc.introduce()
zc.howOld()()
这个题很难不让人想到如下代码,都是函数嵌套,具体解法是类似的,可以对比来看一下啊。
const User = {
name: ‘zc’;
age: 18;
introduce = function () {
console.log(this.name)
}
howOld = function () {
return function () {
console.log(this.age)
}
}
}
var name = ‘Tom’;
var age = 18;
User.introduce()
User.howOld()()
-
zc.introduce()
: zc是new创建的实例,this指向zc,打印zc
-
zc.howOld()()
: zc.howOld()返回一个匿名函数,匿名函数为默认绑定,因此打印18(阿包永远 18 )
答案
zc
18
题目6.3:new界的天王山
new
界的天王山,每次看懂后,没过多久就会忘掉,但这次要从根本上弄清楚该题。
接下来一起来品味品味:
function Foo(){
getName = function(){ console.log(1); };
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();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
- 预编译
GO = {
Foo: fn(Foo),
getName: function getName(){ console.log(5) };
}
- 分析后续执行
-
Foo.getName()
: 执行Foo上的getName方法,打印2
-
getName()
: 执行GO中的getName方法,打印4
-
Foo().getName()
// 修改全局GO的getName为function(){ console.log(1); }
getName = function(){ console.log(1) }
// Foo为默认绑定,this -> window
// return window
return this
复制代码
-
Foo().getName()
: 执行window.getName(),打印1
-
Foo()
执行 -
getName()
: 执行GO中的getName,打印1
- 分析后面三个打印结果之前,先补充一些运算符优先级方面的知识(图源: MDN [8] )
从上图可以看到,部分优先级如下: new(带参数列表) = 成员访问 = 函数调用 > new(不带参数列表)
new Foo.getName()
首先从左往右看: new Foo
属于不带参数列表的new(优先级 19 ), Foo.getName
属于成员访问(优先级 20 ), getName()
属于函数调用(优先级 20 ),同样优先级遵循从左往右执行。
-
Foo.getName
执行,获取到Foo上的getName
属性 -
此时原表达式变为
new (Foo.getName)()
,new (Foo.getName)()
为带参数列表(优先级 20 ),(Foo.getName)()
属于函数调用(优先级 20 ),从左往右执行
new (Foo.getName)()
2
Foo.getName()
这里有一个误区:很多人认为这里的 new
是没做任何操作的的,执行的是函数调用。那么如果执行的是 Foo.getName()
,调用返回值为 undefined
, new undefined
会发生报错,并且我们可以验证一下该表达式的返回结果。
console.log(new Foo.getName())
// 2
// Foo.getName {}
可见在成员访问之后,执行的是 带参数列表格式的new 操作。
new Foo().getName()
步骤4
new Foo()
Foo
Foo
getName
Foo.prototype.getName
3
new new Foo().getName()
从左往右分析: 第一个new不带参数列表(优先级 19 ), new Foo()
带参数列表(优先级 20 ),剩下的成员访问和函数调用优先级都是 20
new Foo()
执行,返回一个以Foo
为构造函数的实例
Foo
Foo.prototype
getName
new (new Foo().getName)()
Foo.prototype.getName()
3
new Foo.getName()
与new new Foo().getName()
区别:
-
new Foo.getName()
的构造函数是Foo.getName
-
new new Foo().getName()
的构造函数为Foo.prototype.getName
测试结果如下:
foo1 = new Foo.getName()
foo2 = new new Foo().getName()
console.log(foo1.constructor)
console.log(foo2.constructor)
输出结果:
2
3
ƒ (){ console.log(2); }
ƒ (){ console.log(3); }
通过这一步比较应该能更好的理解上面的执行顺序。
答案
兄弟们,革命快要成功了,再努力一把,以后this都小问题啦。
7.箭头函数
箭头函数没有自己的 this
,它的 this
指向外层作用域的 this
,且指向函数定义时的 this
而非执行时。
this指向外层作用域的this
this
this
指向函数定义时的this而非执行时
:JavaScript
是静态作用域,就是函数定义之后,作用域就定死了,跟它执行时的地方无关。更详细的介绍见 JavaScript之静态作用域与动态作用域 [9] 。
题目7.1:对象方法使用箭头函数
name = ‘tom’
const obj = {
name: ‘zc’,
intro: () => {
console.log('My name is ’ + this.name)
}
}
obj.intro()
上文说到,箭头函数的 this
通过作用域链查到, intro
函数的上层作用域为 window
。
答案
My name is tom
题目7.2:箭头函数与普通函数比较
name = ‘tom’
const obj = {
name: ‘zc’,
intro:function () {
return () => {
console.log('My name is ’ + this.name)
}
},
intro2:function () {
return function() {
console.log('My name is ’ + this.name)
}
}
}
obj.intro2()()
obj.intro()()
obj.intro2()()
: 不做赘述,打印My name is tom
obj.intro()()
obj.intro()
this
this
obj
My name is zc
题目7.3:箭头函数与普通函数的嵌套
name = ‘window’
const obj1 = {
name: ‘obj1’,
intro:function () {
console.log(this.name)
return () => {
console.log(this.name)
}
}
}
const obj2 = {
name: ‘obj2’,
intro: ()=> {
console.log(this.name)
return function() {
console.log(this.name)
}
}
}
const obj3 = {
name: ‘obj3’,
intro: ()=> {
console.log(this.name)
return () => {
console.log(this.name)
}
}
}
obj1.intro()()
obj2.intro()()
obj3.intro()()
obj1.intro()()
题目7.2
obj1,obj1
obj2.intro()()
obj2.intro()
this
this
window
window,window
obj3.intro()()
obj3.intro()
obj2.intro()
intro
this
window
window,window
答案
obj1
obj1
window
window
window
window
题目7.4:new碰上箭头函数
function User(name, age) {
this.name = name;
this.age = age;
this.intro = function(){
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以送给我的读者朋友们
目录:
Java面试核心知识点
一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!
Java面试核心知识点
已经有读者朋友靠着这一份Java面试知识点指导拿到不错的offer了
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
window` 。
答案
My name is tom
题目7.2:箭头函数与普通函数比较
name = ‘tom’
const obj = {
name: ‘zc’,
intro:function () {
return () => {
console.log('My name is ’ + this.name)
}
},
intro2:function () {
return function() {
console.log('My name is ’ + this.name)
}
}
}
obj.intro2()()
obj.intro()()
obj.intro2()()
: 不做赘述,打印My name is tom
obj.intro()()
obj.intro()
this
this
obj
My name is zc
题目7.3:箭头函数与普通函数的嵌套
name = ‘window’
const obj1 = {
name: ‘obj1’,
intro:function () {
console.log(this.name)
return () => {
console.log(this.name)
}
}
}
const obj2 = {
name: ‘obj2’,
intro: ()=> {
console.log(this.name)
return function() {
console.log(this.name)
}
}
}
const obj3 = {
name: ‘obj3’,
intro: ()=> {
console.log(this.name)
return () => {
console.log(this.name)
}
}
}
obj1.intro()()
obj2.intro()()
obj3.intro()()
obj1.intro()()
题目7.2
obj1,obj1
obj2.intro()()
obj2.intro()
this
this
window
window,window
obj3.intro()()
obj3.intro()
obj2.intro()
intro
this
window
window,window
答案
obj1
obj1
window
window
window
window
题目7.4:new碰上箭头函数
function User(name, age) {
this.name = name;
this.age = age;
this.intro = function(){
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-ldsN1Wa7-1713298770445)]
[外链图片转存中…(img-mmgWyeTp-1713298770446)]
[外链图片转存中…(img-M9oR44Oh-1713298770446)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
本人也收藏了一份Java面试核心知识点来应付面试,借着这次机会可以送给我的读者朋友们
目录:
[外链图片转存中…(img-DAT2sNon-1713298770446)]
Java面试核心知识点
一共有30个专题,足够读者朋友们应付面试啦,也节省朋友们去到处搜刮资料自己整理的时间!
[外链图片转存中…(img-gXQ6LU9y-1713298770447)]
Java面试核心知识点
已经有读者朋友靠着这一份Java面试知识点指导拿到不错的offer了
[外链图片转存中…(img-l96NgxxT-1713298770447)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!