javascript学习
声明
var
变量声明,通俗来说会将变量上升到上级代码块的变量范围中。这里的上级代码块详细来说应该是当前函数作用域或者全局作用域,因为在 JavaScript 里,只有函数和全局作用域能够限制var
变量的作用域,像if
语句、for
循环、while
循环等代码块是无法限制的。
比如:
无法限制var
作用域的情况:1
2
3
4if(true){
var x = 5;
}
console.log(x);//x的值为5可以限制
var
作用域的情况:1
2
3
4
5
6
7
8function example() {
if (true) {
var x = 5; // 实际上会被提升到函数顶部
}
console.log(x); // 可以访问 x,输出 5
}
console.log(x); // 报错:ReferenceError(x 不在全局作用域,因为function将其限制)
函数
函数定义与声明
二者区别
函数声明(Function Declaration)
1 | function add(a, b) { |
特点:
- 以
function
关键字开头,后跟函数名。 - 函数提升(Hoisting):可以在定义前调用(JavaScript 引擎会将函数声明提升到当前作用域的顶部)。
- 独立语句:不能嵌套在非代码块中(如
if
语句、赋值语句)。
- 以
示例:
1
2
3
4console.log(add(2, 3)); // ✅ 可以在定义前调用
function add(a, b) {
return a + b;
}
2. 函数表达式(Function Expression)
1 | const add = function(a, b) { |
特点:
- 以
function
关键字开头(匿名函数),或使用具名函数表达式(如function add(a, b)
)。 - 赋值给变量:函数是一个值,存储在变量
add
中。 - 没有函数提升:必须在定义后调用(变量提升但值为
undefined
)。
- 以
示例:
1
2
3
4console.log(add(2, 3)); // ❌ 报错:add is not a function
const add = function(a, b) {
return a + b;
};
3. 箭头函数(Arrow Function)
1 | const add = (a, b) => a + b; |
特点:
- 更简洁的语法:使用
=>
符号,省略function
关键字。 - 隐式返回:单行表达式无需
return
关键字(如(a, b) => a + b
)。 - 没有自己的
this
:继承自父作用域(适合回调函数)。 - 不能使用
arguments
对象:不绑定arguments
变量。
- 更简洁的语法:使用
示例:
1
2
3
4
5
6
7
8
9
10// 完整语法
const add = (a, b) => {
return a + b;
};
// 隐式返回
const double = num => num * 2;
// 无参数
const greet = () => "Hello!";
箭头函数是函数表达式的一种吗?
是的!
JS原型链
Object.create
的作用
简单来说,该函数就是为了使一个原型对象继承自另一个原型对象,并且仅仅止步于继承另一个原型对象,它本身的修改不会对原型对象进行影响,比如:
1
Child.prototype() = Parent.prototype()
此时,
Child
和Parent
将共享同一个原型对象。修改Child.prototype
会直接影响Parent.prototype
,反之亦然。
所以我们可以使用:1
Child.prototype() = Object.create(Parent.prototype)
此时
Child
继承Parent
的方法属性,但是后续对Child
进行修改也不会影响Parent
本身自带的属性
Parent.call(this, name)
的作用
call()
的基本语法
call()
是所有函数都有的方法,用于显式指定函数执行时的 this
值。语法:
1 | functionName.call(thisArg, arg1, arg2, ...); |
thisArg
:函数执行时this
指向的对象arg1, arg2
:传递给函数的参数
2. 在继承中的作用:属性继承
在构造函数模式中,Parent.call(this, name)
的作用是:
- 在
Child
实例的上下文中执行Parent
构造函数 - 让
Parent
构造函数中的this
指向Child
实例 - 从而将
Parent
的属性添加到Child
实例上
示例解析:
1 | function Parent(name) { |
执行 new Child("Alice", 18)
时:
- 创建一个新的
Child
实例 Parent.call(this, "Alice")
在该实例上添加name
属性- 接着
this.age = 18
添加age
属性
1 | const c = new Child("Alice", 18); |
**简单来说:**就是对某个实例对象的方法进行调用,但是整体不会继承该实例对象,其他的属性不会得到继承。
constructor
属性的作用
什么是 constructor
?
每个对象都有一个 constructor
属性,它指向创建该对象的构造函数。默认情况下,JavaScript 会为原型对象自动添加这个属性。
例如:
1 | function Parent() {} |
为什么需要手动修正 Child.prototype.constructor
?
当你使用 Object.create()
设置原型时,会切断默认的 constructor
关联:
1 | Child.prototype = Object.create(Parent.prototype); |
这是因为 Object.create(Parent.prototype)
创建的新对象继承了 Parent.prototype
的 constructor
属性(即 Parent
)。
手动修正的目的:
1 | Child.prototype.constructor = Child; |
这样做确保:
new Child().constructor === Child
- 保持语言的一致性(虽然这更多是语义上的修复,对功能影响不大
附加小结
prototype
,即原型链属性,在js中主要与,函数,对象,类有关。或者说,它在这三个类型的数据上适用。