山东外贸网站推广,共青城网站建设,怎样查询二级建造师注册情况,法库网站建设1、简述JavaScript中map和foreach的区别#xff1f;
map和forEach都是JavaScript数组的迭代方法#xff0c;但它们之间存在一些关键区别。 返回值#xff1a;map方法会返回一个新的数组#xff0c;这个新数组是由原数组通过某个函数处理后的结果组成的。而forEach方法则没…1、简述JavaScript中map和foreach的区别
map和forEach都是JavaScript数组的迭代方法但它们之间存在一些关键区别。 返回值map方法会返回一个新的数组这个新数组是由原数组通过某个函数处理后的结果组成的。而forEach方法则没有返回值它仅仅是对数组中的每个元素执行一次给定的函数。 修改原数组forEach方法可以直接修改原数组而map方法则不会改变原数组而是创建一个全新的数组。 性能在大多数现代浏览器中map的性能通常优于forEach。
让我们来看一个例子
let arr [1, 2, 3, 4, 5];// 使用map
let mapResult arr.map(num num * 2);
console.log(mapResult); // 输出[2, 4, 6, 8, 10]
console.log(arr); // 输出[1, 2, 3, 4, 5]// 使用forEach
let forEachResult [];
arr.forEach(num forEachResult.push(num * 2));
console.log(forEachResult); // 输出[2, 4, 6, 8, 10]
console.log(arr); // 输出[1, 2, 3, 4, 5]在这个例子中我们可以看到尽管map和forEach都可以对数组中的每个元素执行同样的操作乘以2但map返回了一个新的数组原数组并没有改变而forEach则没有返回值我们需要创建一个新的数组来存储结果。同时原数组在forEach操作后也没有发生改变。
2、解释下JavaScript中this是如何工作的
在 JavaScript 中this关键字是一个特殊的变量它在每个函数作用域内都有定义。它的值取决于函数如何被调用。
全局作用域或函数调用 在全局作用域或者普通函数调用中this指向全局对象也就是window在浏览器中或者global在Node.js中。
console.log(this); // 输出Window {...}function test() {console.log(this);
}
test(); // 输出Window {...}作为对象方法调用 当函数作为对象的一个方法被调用时this指向这个对象。
const obj {name: Alice,sayHello: function() {console.log(this.name);}
};
obj.sayHello(); // 输出Alice作为构造函数调用 当使用new关键字调用函数时this指向新创建的对象。
function Person(name) {this.name name;
}let alice new Person(Alice);
console.log(alice.name); // 输出Alice在事件处理函数中 在 DOM 事件处理函数中this通常指向触发事件的元素。
button.addEventListener(click, function() {console.log(this); // 输出触发点击事件的button元素
});箭头函数 箭头函数没有自己的this它会捕获其所在即定义的位置上下文的this值。
const obj {name: Alice,sayHello: function() {setTimeout(() {console.log(this.name); // 输出Alice}, 1000);}
};
obj.sayHello();使用callapplybind调用 使用callapply或bind方法可以设置函数运行时的this值。
function greet() {console.log(Hello, ${this.name});
}const alice { name: Alice };
const bob { name: Bob };greet.call(alice); // 输出Hello, Alice
greet.call(bob); // 输出Hello, Bob总的来说this的值是在函数被调用时确定的而不是在函数被定义时确定。这就是 JavaScript 中的动态作用域。
3、JavaScript阻止事件冒泡的方法
在JavaScript中阻止事件冒泡可以使用事件对象的stopPropagation方法。当事件发生时浏览器会创建一个事件对象这个对象包含了与事件相关的各种信息和方法其中就包括stopPropagation方法。
这个方法可以阻止当前事件继续向上层元素传播也就是停止事件冒泡。
我们来看一个例子
document.querySelector(#child).addEventListener(click, function(event) {event.stopPropagation();console.log(Child element clicked!);
});document.querySelector(#parent).addEventListener(click, function() {console.log(Parent element clicked!);
});在这个例子中当你点击ID为child的元素时浏览器会首先执行该元素的点击事件处理函数然后因为我们调用了event.stopPropagation()事件就不会继续向上冒泡到父元素也就是ID为parent的元素。所以你只会看到控制台打印出Child element clicked!“而不会看到Parent element clicked!”。
需要注意的是stopPropagation只能阻止事件向上冒泡但不能阻止其他同级事件监听器的执行。如果你希望完全阻止事件的进一步传播包括阻止其他同级事件监听器的执行你可以使用event.stopImmediatePropagation()方法。
4、JavaScript阻止默认事件
在JavaScript中阻止默认事件可以使用事件对象的preventDefault方法。很多浏览器的事件都有默认的行为例如点击链接会跳转到新的页面提交表单会刷新页面等。如果我们不希望触发这些默认行为就可以使用preventDefault方法。
下面是一个例子展示了如何阻止链接的默认跳转行为
document.querySelector(a).addEventListener(click, function(event) {event.preventDefault();console.log(Link clicked, but default action is prevented.);
});在这个例子中当你点击链接时浏览器会首先执行链接的点击事件处理函数。然后因为我们调用了event.preventDefault()链接的默认跳转行为就被阻止了。所以你会看到控制台打印出Link clicked, but default action is prevented.但页面并不会跳转到链接的目标地址。
需要注意的是不是所有的事件都有默认行为只有部分事件才有。对于没有默认行为的事件调用preventDefault方法没有任何效果。另外一些事件的默认行为无法被取消例如页面的unload事件。对于这些事件调用preventDefault方法也没有任何效果。
5、简述 Javascript 盒子模型?
在 Web 开发中CSS 盒模型是用来布局和设计的基本概念。在 CSS 盒模型中每个元素都被视为一个矩形的盒子这个盒子具有宽度、高度、边距、填充和边框。
盒模型主要包含四个部分 内容Content 这是盒子里面的实际内容如文本、图片等。其尺寸可以通过 width 和 height 属性来设置。 内边距Padding 内边距是内容周围的空白区域它清晰地隔离了内容和边框。内边距的大小可以通过 padding 属性来设置。 边框Border 边框就像是盒子的外壳它包围了内容和内边距。边框的大小和样式可以通过 border 属性来设置。 外边距Margin 外边距是盒子和其他元素之间的空白区域。它在边框的外面用来隔离盒子和其他元素。外边距的大小可以通过 margin 属性来设置。
在 CSS 中盒模型有两种标准盒模型和IE盒模型。 标准盒模型 在这个模型中width 和 height 指的是内容区的宽度和高度而不包括内边距、边框和外边距。总的盒子大小计算公式为总宽度 width padding-left padding-right border-left border-right margin-left margin-right高度同理。 IE盒模型 在这个模型中width 和 height 指的是内容区、内边距和边框的总宽度和高度。外边距不包括在内。总的盒子大小计算公式为总宽度 width margin-left margin-right高度同理。
可以使用 CSS 的 box-sizing 属性来选择使用哪种盒模型content-box 为标准盒模型border-box 为IE盒模型。
6、Javascipt中async await 和promise和generator有什么区别
async/await、Promise 和 generator 都是 JavaScript 中用于处理异步操作的工具但它们的使用方式和机制各有不同。
Promise Promise 是 JavaScript 中处理异步操作的一个对象。它有三种状态pending待定、fulfilled已成功和 rejected已失败。Promise 在创建时处于 pending 状态然后可能转换为 fulfilled 或 rejected 状态。一旦状态改变就不能再次改变。Promise 可以使用 then 和 catch 方法来处理成功或失败的结果。
let promise new Promise((resolve, reject) {// 异步操作if (/* 成功 */) {resolve(value);} else {reject(error);}
});promise.then(value {// 处理成功的结果
}).catch(error {// 处理错误
});Generator Generator 是 ES6 引入的一种新的函数类型它可以在执行过程中被暂停和恢复。Generator 使用 yield 关键字来暂停函数的执行使用 next 方法来恢复执行。Generator 可以用于处理异步操作但需要配合其他工具如 Promise使用。
function* myGenerator() {const data yield doAsyncOperation();console.log(data);
}const generator myGenerator();
generator.next().value.then(data {generator.next(data);
});Async/Await Async/Await 是 ES7 引入的一种新的处理异步操作的方式它是基于 Promise 的。Async/Await 使用 async 和 await 关键字使得异步代码看起来像同步代码。这大大提高了代码的可读性和可维护性。
async function myAsyncFunction() {try {const data await doAsyncOperation();console.log(data);} catch (error) {// 处理错误}
}myAsyncFunction();总的来说Promise 提供了一种在异步操作完成后处理结果的方式Generator 提供了一种可以暂停和恢复的函数而 Async/Await 则提供了一种更简洁、更直观的处理异步操作的方式。
7、JavaScript中手写promise
在 JavaScript 中Promise 是一个代表了异步操作最终完成或者失败的对象。我们可以手动创建一个 Promise如下所示
function MyPromise(executor) {let self this;self.status pending; // Promise 当前的状态self.value undefined; // Promise 的值self.reason undefined; // Promise 失败的原因// 成功function resolve(value) {if (self.status pending) {self.status fulfilled;self.value value;}}// 失败function reject(reason) {if (self.status pending) {self.status rejected;self.reason reason;}}try {executor(resolve, reject);} catch (error) {reject(error);}
}MyPromise.prototype.then function(onFulfilled, onRejected) {let self this;if (self.status fulfilled) {onFulfilled(self.value);}if (self.status rejected) {onRejected(self.reason);}
}这是一个最基础的 Promise 实现它包含了 Promise 的基本逻辑。但是这个实现还缺少很多真正的 Promise 具备的功能比如链式调用、异步支持、错误处理、catch 方法、Promise.all 方法、Promise.race 方法等等。
在实际开发中我们通常使用内置的 Promise 对象因为它已经实现了完整的功能并且经过了大量的测试和优化。
8、JavaScript中promise.all作用
Promise.all 是 JavaScript 中的一个 Promise 方法它接收一个 Promise 对象的数组作为参数返回一个新的 Promise 对象。这个新的 Promise 对象只有在所有的 Promise 对象都成功地完成fulfilled时才会完成如果有任何一个 Promise 对象失败rejected了那么新的 Promise 对象会立即失败。
在所有的 Promise 对象都成功完成时新的 Promise 对象的结果会是一个数组这个数组包含了每个 Promise 对象的结果。这些结果的顺序和原来的 Promise 对象的顺序一致。
如果有任何一个 Promise 对象失败了新的 Promise 对象的结果会是那个失败的 Promise 对象的结果。
下面是一个例子
let promise1 Promise.resolve(3);
let promise2 42;
let promise3 new Promise((resolve, reject) {setTimeout(resolve, 100, foo);
});Promise.all([promise1, promise2, promise3]).then(values {console.log(values); // 输出[3, 42, foo]
});在这个例子中Promise.all 接收了三个 Promise 对象当这三个 Promise 对象都成功完成时它返回的 Promise 对象也成功完成结果是一个包含了每个 Promise 对象结果的数组。
Promise.all 在处理多个相互独立的异步操作并且需要等待所有异步操作都完成时非常有用。
9、Javascript 浅拷贝/深度拷贝的区别
在 JavaScript 中浅拷贝和深拷贝都是用来复制对象的但它们复制的深度不同。
浅拷贝Shallow Copy 浅拷贝只复制对象的顶层属性。如果对象的属性值是基本类型如数字、字符串、布尔值那么就直接复制这个值如果属性值是引用类型如对象、数组那么复制的是这个值的引用而不是实际的对象或数组。这就意味着如果你修改了新对象的一个引用类型的属性那么原对象的对应属性也会被修改。
let obj1 { a: 1, b: [1, 2, 3] };
let obj2 {...obj1};
obj2.b.push(4);
console.log(obj1.b); // 输出[1, 2, 3, 4]在这个例子中我们使用了对象扩展运算符…来创建一个新的对象这是一种浅拷贝的方式。当我们修改了新对象的 b 属性时原对象的 b 属性也被修改了。
深拷贝Deep Copy 深拷贝不仅复制对象的顶层属性还会递归地复制所有的子属性。无论属性值是基本类型还是引用类型都会创建一个新的副本。这就意味着新对象和原对象完全独立修改其中一个不会影响另一个。
let obj1 { a: 1, b: [1, 2, 3] };
let obj2 JSON.parse(JSON.stringify(obj1));
obj2.b.push(4);
console.log(obj1.b); // 输出[1, 2, 3]在这个例子中我们使用了 JSON.stringify 和 JSON.parse 方法来创建一个新的对象这是一种深拷贝的方式。当我们修改了新对象的 b 属性时原对象的 b 属性没有被修改。
需要注意的是使用 JSON.stringify 和 JSON.parse 方法进行深拷贝有一些限制比如无法复制函数和循环引用的对象等。在实际开发中我们通常会使用一些库如 lodash的深拷贝函数因为这些函数已经处理了各种边缘情况。
10、Javascript 闭包是什么,闭包形成的原因和闭包的用途
闭包Closure是 JavaScript 中的一个非常重要的概念。简单地说闭包就是一个函数能够访问另一个函数的作用域。这是因为在 JavaScript 中函数是一等公民可以作为参数传递也可以作为返回值返回。当一个函数 A 返回另一个函数 B并且这个函数 B 中使用了函数 A 的变量那么这时候就产生了闭包。
闭包形成的原因主要是因为 JavaScript 的词法作用域lexical scoping机制。词法作用域意味着函数的作用域在函数定义的时候就已经确定了而不是在函数调用的时候确定。因此即使外部函数已经返回闭包依然能够访问外部函数的变量。
闭包的用途很广泛主要有以下几点
模拟私有变量在 JavaScript 中我们没有真正意义上的私有变量但我们可以通过闭包来模拟私有变量。例如
function createCounter() {let count 0; // 这个变量在外部是无法访问的return function() {return count;};
}let counter createCounter();
console.log(counter()); // 1
console.log(counter()); // 2在这个例子中count 变量对于外部是不可见的只有通过 counter 函数才能访问和修改。 延长局部变量的生命周期正常情况下函数的局部变量在函数执行完之后就会被销毁。但是如果我们创建了一个闭包并且这个闭包引用了一些局部变量那么这些局部变量就会一直存在直到闭包被销毁。这可以用来保存函数的状态。 实现某些设计模式如模块模式Module Pattern使用闭包可以实现一个模块具有公开的方法和隐藏的私有方法或变量这是模块模式的基础。
以上就是关于 JavaScript 闭包的一些基本解释和应用场景。希望对您有所帮助
11、Javascript 跨域的解决方案有哪些
跨域问题是由于浏览器的同源策略导致的。同源策略是一种约定它是浏览器为了安全性而采取的策略即浏览器要求所有的请求必须与当前页面的协议、主机名和端口号完全一致否则就视为跨域。
解决跨域问题的常见方法有以下几种 JSONPJSONP 是一种常用的跨域数据交互的方法。它通过动态插入 script 标签来获取数据因为 script 标签的 src 属性不受同源策略的限制。但是 JSONP 只能发送 GET 请求且不安全。 CORS跨源资源共享CORS是一种现代并且安全的跨域请求技术。服务器可以在响应头中添加一些 CORS 相关的头信息如 Access-Control-Allow-Origin来告诉浏览器允许特定的跨域请求。 代理服务器通过服务器来转发请求和响应因为服务器端没有同源策略的限制。例如在 Node.js 中我们可以使用 http-proxy-middleware 这样的中间件来实现。 使用 WebSocketWebSocket 是一种通讯协议不受同源策略的限制可以用来实现跨域通信。 使用 postMessage APIHTML5 引入的 postMessage API 可以实现跨域通信。两个窗口或者 iframe 和其父窗口可以通过 postMessage 和 onmessage 实现数据的传递。 使用 document.domain这种方法只能用于二级域名相同的情况。 使用 window.namewindow 对象有一个 name 属性这个属性在页面跳转时不会改变可以通过它来传递数据。 使用 location.hash通过改变 URL 的 hash# 后面的部分来传递数据这种方法通常用于 iframe 间的通信。
以上就是一些常见的解决跨域问题的方法具体使用哪一种方法需要根据具体的应用场景和需求来决定。
12、Http协议详解 Http请求方式有 Http响应状态码 ?
HTTP协议HTTPHyperText Transfer Protocol是一种无状态的、应用层的协议主要用于在用户端通常是 Web 浏览器和服务器端之间传输数据。HTTP 是基于 TCP/IP 协议的它通过请求和响应的方式来进行通信。
HTTP 请求方法HTTP 定义了一组请求方法也被称为“动词”用来描述对资源的不同操作
GET获取资源。POST提交数据通常会改变服务器的状态。PUT更新资源。DELETE删除资源。HEAD类似于 GET但是只返回 HTTP 头部信息不返回实体内容。OPTIONS获取资源支持的操作类型。PATCH对资源进行部分修改。
HTTP 响应状态码HTTP 响应状态码用来表示服务器对请求的处理结果。常见的有
1xx信息响应表示请求已被接收需要继续处理。2xx成功表示请求已成功被服务器接收、理解、并接受。 200 OK请求成功。 3xx重定向需要后续操作才能完成请求。 301 Moved Permanently资源永久性转移。302 Found资源临时性转移。 4xx客户端错误表示请求含有语法错误或者无法被服务器执行。 400 Bad Request请求语法错误。401 Unauthorized请求需要认证。403 Forbidden服务器拒绝请求。404 Not Found请求的资源无法找到。 5xx服务器错误表示服务器在处理请求的过程中发生了错误。 500 Internal Server Error服务器内部错误。503 Service Unavailable服务器暂时无法处理请求。
以上就是对 HTTP 协议、请求方法和响应状态码的简单介绍。
13、JavaScript什么是长连接
长连接也被称为持久连接、keep-alive连接或者连接保持是一种通信机制它允许客户端和服务器在一个连接上发送多个请求和响应而不需要为每个请求/响应对创建新的连接。这种机制可以显著地降低服务器的负载提高资源的使用率。
在 HTTP/1.0 中每一个 HTTP 请求/响应对都需要建立一个新的 TCP 连接这会带来很大的开销。而在 HTTP/1.1 中引入了长连接的概念允许在一个连接上进行多次 HTTP 交互直到客户端或者服务器主动关闭连接。
在 JavaScript 中我们可以使用 XMLHttpRequest 或 Fetch API 发送 HTTP 请求它们默认都会使用长连接。此外我们还可以使用 WebSocket 或 Server-Sent Events 来实现真正的双向长连接这两种技术都允许服务器主动向客户端推送数据。
例如WebSocket 可以用来实现实时聊天、多人游戏、实时数据更新等功能。在这些场景中服务器需要能够随时向客户端推送新的数据而不需要客户端每次都发送请求。WebSocket 通过在客户端和服务器之间建立一个持久的、全双工的连接使得数据可以在任何时间点从任一方向传输。
14、display:none和visibility:hidden的区别是
display: none 和 visibility: hidden 都可以用来隐藏 HTML 元素但是它们之间有一些重要的区别 空间占用当元素被设置为 display: none 时这个元素会从文档流中完全移除就像它从来没有存在过一样。它不会占据任何空间也不会影响到其他元素的布局。而当元素被设置为 visibility: hidden 时这个元素虽然不可见但是它依然会占据空间依然会参与布局。 对子元素的影响display: none 会影响到元素的所有子元素如果一个元素被设置为 display: none那么它的所有子元素也都会被隐藏无论子元素的 display 属性是什么。而 visibility: hidden 不会影响到子元素的 visibility 属性也就是说如果一个元素被设置为 visibility: hidden它的子元素依然可以通过设置 visibility: visible 来显示。 对事件的影响被设置为 display: none 的元素不会响应任何事件例如鼠标点击事件。而被设置为 visibility: hidden 的元素依然可以响应事件例如即使一个按钮被设置为 visibility: hidden用户依然可以通过 Tab 键导航到这个按钮并使用 Enter 键来触发点击事件。
以上就是 display: none 和 visibility: hidden 的主要区别。总的来说display: none 更像是“删除”元素而 visibility: hidden 更像是“隐藏”元素。
15、JavaScript中常用的数组方法
JavaScript 中的数组有许多内置的方法可以帮助我们操作数组。以下是一些常用的数组方法
push()在数组的末尾添加一个或多个元素并返回新的长度。
let arr [a, b, c];
arr.push(d); // 返回 4
console.log(arr); // 输出 [a, b, c, d]pop()删除并返回数组的最后一个元素。
let arr [a, b, c];
let last arr.pop(); // 返回 c
console.log(arr); // 输出 [a, b]shift()删除并返回数组的第一个元素。
let arr [a, b, c];
let first arr.shift(); // 返回 a
console.log(arr); // 输出 [b, c]unshift()在数组的开头添加一个或多个元素并返回新的长度。
let arr [a, b, c];
arr.unshift(0); // 返回 4
console.log(arr); // 输出 [0, a, b, c]splice()在数组中添加或删除元素。
let arr [a, b, c];
arr.splice(1, 0, x); // 在索引为1的位置插入x
console.log(arr); // 输出 [a, x, b, c]slice()返回一个新的数组包含从 start 到 end不包括 end的数组元素。
let arr [a, b, c, d, e];
let newArr arr.slice(1, 3); // 返回 [b, c]sort()对数组的元素进行排序。
let arr [c, a, b];
arr.sort();
console.log(arr); // 输出 [a, b, c]reverse()颠倒数组中元素的顺序。
let arr [a, b, c];
arr.reverse();
console.log(arr); // 输出 [c, b, a]join()将所有的数组元素连接成一个字符串。
let arr [a, b, c];
let str arr.join(-); // 返回 a-b-cmap()创建一个新数组其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
let arr [1, 2, 3];
let newArr arr.map(x x * 2); // 返回 [2, 4, 6]filter()创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
let arr [1, 2, 3, 4, 5];
let newArr arr.filter(x x 3); // 返回 [4, 5]reduce()对数组中的每个元素执行一个由您提供的 reducer 函数(升序执行)将其结果汇总为单个返回值。
let arr [1, 2, 3, 4, 5];
let sum arr.reduce((acc, cur) acc cur, 0); // 返回 15以上就是 JavaScript 中常用的数组方法。
16、手写防抖、节流防抖和节流的区别
防抖debounce如果一个函数持续地触发那么只在它停止触发的一段时间后才执行如果在这段时间内又开始持续触发则重新计算时间。
防抖函数的实现如下
function debounce(func, wait) {let timeout;return function() {clearTimeout(timeout);timeout setTimeout(() {func.apply(this, arguments);}, wait);};
}节流throttle如果一个函数持续地触发那么固定在一段时间内只执行一次。
节流函数的实现如下
function throttle(func, wait) {let lastTime 0;return function() {let now Date.now();if (now - lastTime wait) {func.apply(this, arguments);lastTime now;}};
}防抖和节流的区别
防抖是让连续触发的函数在一段时间后只执行一次如果在这段时间内又触发了该函数则重新计算时间。适用场景文本输入的验证连续输入文字后发送 AJAX 请求进行验证验证一次就好。节流是让连续触发的函数在一段时间内只执行一次并且这段时间内的多次触发只会计算一次。适用场景滚动加载时间间隔内只加载一次模拟鼠标移动mousemove监听滚动事件比如是否滑到底部自动加载更多用 throttle 是为了降低频率。
17、Javascipt的call和apply的区别
call 和 apply 都是 Function 对象的方法它们都可以用来改变函数的 this 上下文并立即调用这个函数。它们的主要区别在于参数的传递方式
call 方法接受的是参数列表第一个参数是 this 的值之后是传递给函数的参数。例如
function greet(name, age) {console.log(Hello, my name is ${name} and I am ${age} years old.);
}greet.call(, Alice, 25); // 输出 Hello, my name is Alice and I am 25 years old.apply 方法接受的是一个参数数组第一个参数同样是 this 的值第二个参数是一个数组其中包含了传递给函数的参数。例如
function greet(name, age) {console.log(Hello, my name is ${name} and I am ${age} years old.);
}greet.apply(, [Alice, 25]); // 输出 Hello, my name is Alice and I am 25 years old.在 ES6 中你还可以使用扩展运算符spread operator和 apply 达到和 call 相同的效果
greet.apply(, [Alice, 25]); // 使用 apply
greet(...[Alice, 25]); // 使用扩展运算符效果和上面一样总的来说call 和 apply 的功能是相同的只是参数的传递方式不同。你可以根据实际需求选择使用哪一个。
18、JavaScript 闭包是什么有什么特性对页面有什么影响?简要介绍你理解的闭包
闭包是JavaScript中一种非常重要的概念它的定义可能有点抽象闭包是指有权访问另一个函数作用域中的变量的函数创建闭包的常见方式就是在一个函数内部创建另一个函数。
闭包的特性主要包括以下几点
函数嵌套外部函数中嵌套内部函数内部函数可以访问外部函数的变量和参数。变量引用即使外部函数已经返回内部函数仍然可以引用外部函数的变量和参数。内存消耗由于内部函数保持了对外部函数变量的引用所以这些变量不会被垃圾收集器回收可能会导致内存消耗。
闭包的影响主要体现在以下几个方面
数据封装和私有成员通过闭包我们可以创建私有变量防止外部访问达到数据封装和保护的目的。持久化变量闭包可以使得函数中的变量在函数执行完毕后仍然保存在内存中可用于在不同函数调用间保持状态。
举个例子说明闭包
function outerFunction() {var count 0;function innerFunction() {count;console.log(count);}return innerFunction;
}var instance outerFunction();
instance(); // 输出1
instance(); // 输出2在这个例子中outerFunction返回了innerFunction并且innerFunction引用了outerFunction的count变量。即使outerFunction已经执行完毕但是由于innerFunction对count的引用count变量仍然存在每次调用instance()count都会增加并打印出来。这就是闭包的一个典型的应用场景。
19、阐述Javascript的同源策略
同源策略Same-origin policy是一种重要的安全策略它被用于限制从同一源加载的文档或脚本如何与来自其他源的资源进行交互。这是一种防止恶意行为的重要安全机制。
在JavaScript中如果两个网页的协议端口如果有的话和主机都相同那么这两个网页属于同源。这意味着http://www.example.com/dir/page1.html 和 http://www.example.com/dir/page2.html 是同源的。
但是以下例子则不属于同源
http://www.example.com 和 https://www.example.com 协议不同http://www.example.com:80 和 http://www.example.com:81 端口不同http://www.example.com 和 http://en.example.com 主机不同
同源策略的主要影响包括
Cookie、LocalStorage 和 IndexDB 无法读写。DOM 无法获得和操作。AJAX 请求不能发送。
当然也有一些方法可以在不同源的情况下进行数据通信比如 JSONP、CORS跨源资源共享等。
比如CORS是一种W3C标准它允许服务器使用特定的HTTP头来告诉浏览器它允许来自其他源的请求。这样即使是不同源我们也可以在满足CORS策略的条件下进行数据通信。
由于内容太多更多内容以链接形势给大家点击进去就是答案了
20. Javascript 阐述This对象的理解
21. DOM怎样添加、移除、移动、复制、创建和查找节点
22. Javascript null和undefined的区别
23. Javascript中callee和caller的作用
24. Javascript垃圾回收方法
25. JavaScript原型原型链 ? 有什么特点
26. JavaScript的数据对象有那些属性值
27. Javascript 描述以下变量的区别nullundefined或undeclared
28. 请指出JavaScript宿主对象和原生对象的区别
29. 简述attribute和property的区别
30. 请指出document.onload和document.ready两个事件的区别
31. Javascript 和有什么不同
32. JavaScript里函数参数arguments是数组吗
33. Javascript 什么是use strict?使用它的好处和坏处分别是什么?
34. 阐述JavaScript事件委托是什么
35. 简述在Javascript中什么是伪数组如何将伪数组转化为标准数组
36. JavaScript中的split、slice、splice函数区别
37. 全面阐述JavaScript ES6的理解
38. 简述Javascript isNan() 函数
39. JavaScript 中的负无穷大是什么
40. JavaScrpit隐式类型强制有什么作用举个例子
41. 简述JavaScript 中的 NaN 是什么
42. 简述 JavaScript 中的高阶函数是什么
43. 简述JavaScript中什么是柯里化
44. JavaScript为什么要使用promises
45. 解释为什么要在 JavaScript 中使用严格模式
46. JavaScript语言中preventDefault() 方法有什么作用
47. 简述什么是JSON stringify
48. 简述JavaScript标签中 defer和 async属性的区别
49. 简述为什么不建议在 JavaScript中使用 innerHTML
50. JavaScript如何实现异步编程
51. JavaScript函数声明与函数表达式的区别
52. 简述documen.wrte和 innerHTML的区别是什么
53. 请简述JavaScript语句的基本规范
54. 列出不同浏览器中关于 JavaScript兼容性的两个常见问题
55. JavaScript语言中ViewState和 SessionState有什么区别
56. 如何在 JavaScript中将base字符串转换为 integer
57. 解释JavaScript void0的作用是什么
58. JavaScript转义字符的作用
59. 请区分解释 window. onload和 onDocumentReady
60. 简述JavaScript什么是构造函数它与普通函数有什么区别
61. 请说出 JavaScript无阻塞加载的具体方式
62. 请解释一下JavaScript事件冒泡机制
63. 简述JavaScript什么是事件流
64. 使用 typeof bar object可以确定bar是不是对象的潜在陷阱如何避免这个陷阱
65. 说明下列代码将输出什么并解释原因
66. 解释什么是JavaScript时间死区
67. 解释文档加载与 DOMContentLoaded
68. JavaScript 中有多少个线程
69. 解释JavaScript调试代码时断点机制
70. JavaScript freeze() 方法有什么作用
71. JavaScript NoScript标签有什么作用
72. Promise 的 finally 怎么实现的
73. JavaScript 创建“原生”native方法 ?
74. 请问什么是JavaScript箭头函数以及特性
75. 简述实际开发中闭包的应用
76. 简述JS判断数据类型的方法有哪四种?(列出四种即可
77. 简述Javascript数组怎么去重有哪些方法
78. 如何判断一个对象是不是空对象
79. 简述Set、Map、WeakSet 和 WeakMap 的区别
80. Promise 构造函数是同步执行还是异步执行那么 then 方法呢
81. 简述JavaScript中的常见编码方案
82. 简述JavaScript修饰器
83. 简述ES6 的 class 和构造函数的区别