js进阶(常见问题分析)

本文围绕JavaScript展开,介绍了类型转换、事件委托、闭包等核心知识,分析了“==”和“===”、null和undefined的区别,还提及深拷贝和浅拷贝及实现方式。此外,给出了简单的性能优化方法,最后阐述了线程和进程的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.js类型转换方式

显式转换:parseInt,parseFloat,number

隐式转换:==,===,+,-,*,/,%

 

2,事件委托

利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行

 

3,闭包

闭包就是能够读取其他函数内部变量的函数,使得函数不被GC回收

优点:(1)希望一个变量长期驻扎在内存当中(不被垃圾回收机制回收)   (2)避免全局变量的污染   (3)私有成员的存在   (4)安全性提高

缺点:容易导致内存泄露

 

4, ”==”和“===”的不同

"=="会自动转换类型,再判断是否相等
"==="不会自动类型转换,直接去比较

 

5,null和undefined的区别

null表示没有对象,即该处不应该有值

undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。

 

6,js数据类型

常见数据类型:string, boolean, number,undefined,null

复合数据类型:function, object

 

7,简单的性能优化方法

(1)压缩css、js文件
(2)合并js、css文件,减少http请求
(3)外部js、css文件放在最底下
(4)减少dom操作,尽可能用变量替代不必要的dom操作

 

8,深拷贝和浅拷贝

浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,如果原地址发生改变,那么被拷贝出来的值也会发生改变

深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存,即使原地址发生改变,被拷贝出来的值也不会发生改变

 

9,深拷贝实现的几种方式

(1)json方法实现

//_tmp和result是相互独立的,没有任何联系,有各自的存储空间。
let deepClone = function (obj) {
    let _tmp = JSON.stringify(obj);//将对象转换为json字符串形式
    let result = JSON.parse(_tmp);//将转换而来的字符串转换为原生js对象
    return result;
};

let obj1 = {
    weiqiujaun: {
        age: 20,
        class: 1502
    },
    liuxiaotian: {
        age: 21,
        class: 1501
    }
};

let test = deepClone(obj1);
console.log(test);

 (2)用for...in方式实现

//_tmp和result是相互独立的,没有任何联系,有各自的存储空间。
let deepClone = function (obj) {
    let _tmp = JSON.stringify(obj);//将对象转换为json字符串形式
    let result = JSON.parse(_tmp);//将转换而来的字符串转换为原生js对象
    return result;
};

let obj1 = {
    weiqiujaun: {
        age: 20,
        class: 1502
    },
    liuxiaotian: {
        age: 21,
        class: 1501
    }
};

let test = deepClone(obj1);
console.log(test);

(3)利用数组的Array.protype.forEach

let deepClone = function (obj) {
    let copy = Object.create(Object.getPrototypeOf(obj));
    let propNames = Object.getOwnPropertyNames(obj);
    propNames.forEach(function (items) {
        let item = Object.getOwnPropertyDescriptor(obj, items);
        Object.defineProperty(copy, items, item);

    });
    return copy;
};

let testObj = {
    name: "weiqiujuan",
    sex: "girl",
    age: 22,
    favorite: "play",
    family: {brother: "wei", mother: "haha", father: "heihei"}
}
let testRes2 = deepClone(testObj);
console.log(testRes2);

(4) 使用递归的方式实现

/使用递归的方式实现数组、对象的深拷贝
function deepClone1(obj) {
  //判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
  var objClone = Array.isArray(obj) ? [] : {};
  //进行深拷贝的不能为空,并且是对象或者是
  if (obj && typeof obj === "object") {
    for (key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (obj[key] && typeof obj[key] === "object") {
          objClone[key] = deepClone1(obj[key]);
        } else {
          objClone[key] = obj[key];
        }
      }
    }
  }
  return objClone;
}

(5)lodash函数实现

lodash很热门的函数库,提供了 lodash.cloneDeep()实现深拷贝

 

10,变量提升

js代码执行过程分为两个阶段,第一阶段词法分析,第二阶段代码执行。

console.log(v1);
var v1 = 100;
function foo() {
    console.log(v1);
    var v1 = 200;
    console.log(v1);
}
foo();
console.log(v1);
// undefined  undefined 200  100

 

11,渐进增强和优雅降级

优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效.

渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。

 

12,this指向

this永远指向函数运行时所在的对象,而不是函数被创建时所在的对象。匿名函数或不处于任何对象中的函数指向window 。

  • 1.如果是call,apply,with,指定的this是谁,就是谁。

  • 2.普通的函数调用,函数被谁调用,this就是谁。

 

13,原型继承的原理

function getProperty(obj,prop) {

    if (obj.hasOwnProperty(prop)) {

        return obj[prop];

    } else if (obj.__proto__!==null) {

        return getProperty(obj.__proto__,prop);

    } else {

        return undefined;

    }

}

 

14,同步和异步的区别

同步的概念在操作系统中:不同进程协同完成某项工作而先后次序调整(通过阻塞、唤醒等方式),同步强调的是顺序性,谁先谁后。异步不存在顺序性。
同步:浏览器访问服务器,用户看到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容之后进行下一步操作。
异步:浏览器访问服务器请求,用户正常操作,浏览器在后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。

 

15,线程和进程的区别

线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元;而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务。在引入了线程的操作系统中,通常一个进程都有若干个线程,至少包含一个线程。

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。

内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的

影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值