深入解析JavaScript核心概念:11个关键问题详解

作者:拾光

时间:2026-10-27

浏览:196

本文深入解析JavaScript中11个核心概念,涵盖原始值与引用值的存储差异、undefined与null的区别、伪数组的转换方法、原型链的工作原理以及对象创建的内部机制。通过具体代码示例,阐明构造函数返回值对对象创建的影响、instanceof运算符的原理以及Function与Object的特殊关系,帮助开发者理解JavaScript底层逻辑。

文章目录

原始值与引用值的存储机制

1. 原始值与引用值的存储机制

在JavaScript中,原始值(Primitive Values)通常存储在栈内存(Stack)中,而引用值(Reference Values)则存储在堆内存(Heap)中。以下代码展示了这两种值的定义方式:

代码如下:

function Person(id,name,age){
this.id = id;
this.name = name;
this.age = age;
}
var num = 10;
var bol = true;
var str = "abc";
var obj = new Object();
var arr = ['a','b','c'];
var person = new Person(100,"笨蛋的座右铭",25);

undefined 与 null 的区别

2. undefined 与 null 的区别

undefined 表示变量已声明但未赋值,它是 Undefined 类型的唯一值。

null 表示对象引用为空,它是 Null 类型的唯一值。

通过 typeof 运算符可以观察到以下特性: typeof(undefined) === 'undefined'; typeof(null) === 'object'; undefined == null; // true undefined !== null; // false null instanceof Object; // false undefined instanceof Object; // false

尽管存在 Undefined 和 Null 类型,但它们是不可见的,开发者只能使用它们的值,无法直接访问类型本身。

尝试使用 instanceof 检查这些类型会返回 false: alert(undefined instanceof Undefined); // false alert(null instanceof Null); // false

伪数组的转换与处理

3. 伪数组(Array-like Objects)

伪数组具有以下特征: 1) 拥有 length 属性;

2) 可以通过索引顺序访问数据,类似于数组;

3) 不具备数组特有的操作方法,如 push、pop、slice 等。

可以通过 Array.prototype.slice 将伪数组转换为真正的数组:

var fakeArray = {0: 'a', 1: 'b', length: 2}; // 标准伪数组

var realArray = Array.prototype.slice.call(fakeArray);

JavaScript 中常见的伪数组包括 arguments、node.childNodes 以及 document.getElementsByTagName() 的返回值。

需要注意的是,在 IE 浏览器中,node.childNodes 无法通过 slice 方法进行转换。

jQuery 对象本身也是一个伪数组:

alert($('.class1').length); // 获取长度 alert($('.class1')[0].tagName); // 访问第一个元素的标签名

简单类型字面量的类型检测

4. 简单类型字面量的类型检测

var a = 1; var b = true; var c = "ccc";

字面量在 typeof 检测下显示出具体的类型。

使用 typeof 可以正确识别类型: alert(typeof a); // 'number' alert(typeof b); // 'boolean' alert(typeof c); // 'string'

然而,使用 instanceof 检测时,字面量并不属于对应的包装对象类型。

检测结果如下: alert(a instanceof Number); // false alert(a instanceof Object); // false alert(b instanceof Boolean); // false alert(b instanceof Object); // false alert(c instanceof String); // false alert(c instanceof Object); // false

原型链与对象属性访问

5. 函数的 prototype 属性与对象实例的内部 [[Prototype]]

每个函数(构造函数)都拥有一个 prototype 属性。每个对象实例都有一个内部的 [[Prototype]] 属性(在 Mozilla 浏览器中可通过 __proto__ 访问),该属性指向构造函数的 prototype 属性。prototype 本身也可以拥有自己的 prototype,从而形成原型链。Object 是原型链的顶端,因此所有原型链最终都会指向 Object.prototype。当访问对象实例的属性或方法时,JavaScript 引擎会先从对象自身开始搜索,如果未找到,则沿着原型链向上搜索,直到 Object.prototype 的 [[Prototype]] 为 null 为止。

构造函数的返回值机制

6. 构造函数的返回值秘密

代码如下:

var s = new function(){return "sss"};
alert(s); // '[object Object]'
s = new function(){return new String("sss")};
alert(s); // 'sss'

关于这段代码的解释:

当 new 表达式后的构造函数返回一个引用类型(如数组、对象、函数等)时,new 创建的匿名对象将被覆盖,返回该引用对象。如果构造函数返回原始类型(或未显式 return,此时隐含返回 undefined),则返回 new 创建的匿名对象。

对象的创建过程详解

7. 对象的创建过程

代码如下:

function Person(name){
this.name = name;
}
Person.prototype = {
getName: function(){return this.name}
};
var p = new Person('zhangsan');

解密 p 的创建过程:

1. 创建一个内置对象 obj 并进行初始化;

2. 将 p 的内部 [[Prototype]] 指向 Person.prototype;

3. 将 p 作为 this,使用 arguments 参数调用 Person 的内部 [[Call]] 方法,即执行 Person 函数体,并返回返回值。如果没有 return 语句,则返回 undefined;

4. 如果上一步返回的是对象类型,则将该值赋给 p;否则,返回步骤 1 中创建的 obj。

自有属性与继承属性的区别

8. 对象的自有属性与继承属性

代码如下:

function Person(name){
this.name = name;
}
Person.prototype = {
type: 'human',
getName: function(){return this.name}
};
var p = new Person('zhangsan');
alert(p.hasOwnProperty('type')); // false
p.type = 'ren';
alert(p.hasOwnProperty('type')); // true

运行结果明确表明:对象无法修改原型中的同名属性,而是会在自身创建一个同名属性并赋值。

函数对象的创建过程

9. 函数对象的创建过程

1. 创建一个内置对象 fn;

2. 将 fn 的内部 [[Prototype]] 设置为 Function.prototype;

3. 设置内部的 [[Call]] 属性,这是一个内部方法,用于处理函数调用的逻辑(可简单理解为指向函数体);

4. 设置 fn.length 为 funArgs.length,如果函数没有参数,则将 fn.length 设置为 0;

5. 使 fn.prototype 的 constructor 指向 fn 自身;

6. 返回 fn。

instanceof 运算符原理

10. instanceof 运算符的原理

判断 a 是否为 B 的实例,即检查 B 的 prototype 属性指向的对象是否存在于 a 的原型链上。

Function 与 Object 的特殊关系

11. 关于 Function 和 Object 的相互关系

alert(Function instanceof Function); // true alert(Function instanceof Object); // true alert(Object instanceof Function); // true alert(Object instanceof Object); // true

这一现象反映了 JavaScript 中 Function 和 Object 的特殊地位,Function 是构造函数的构造函数,而 Object 是所有对象的基类。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章