Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the 10 basic questions you need to master in JavaScript?

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

JavaScript needs to master 10 basic problems, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain in detail for you, people with this need can come to learn, I hope you can gain something.

JavaScript is a client-side programming language. More than 90% of websites around the world use it, and it is one of the most commonly used programming languages in the world. Therefore, today we will discuss 10 common questions about JavaScript.

1. How to remove a specific item from an array

Idea: first, use indexOf to find the index (index) of the array element you want to delete, and then use the splice method to delete the item corresponding to the index.

Splice () is an impure function that changes the contents of the array by deleting existing elements and / or adding new elements.

Const array = [2,5,9] const index = array.indexOf (5) if (index >-1) {array.splice (index, 1)} console.log (array) / / [2,9]

The second parameter to splice is the number of elements to delete. Note that splice modifies the array in place and returns a new array containing deleted elements.

Then, we can improve it. There are two functions below. The first function deletes only one match (that is, the first match is removed from [2pje 5je 9pr 1je 5pr 8je 5]), while the second function deletes all matches:

/ / delete only the first match function removeItemOnce (arr, value) {let index = arr.indexOf (value) if (index >-1) {arr.splice (index, 1)} return arr} / / Delete all matches function removeItemAll (arr, value) {let I = 0 while (I

< arr.length) { if (arr[i] === value) { arr.splice(i, 1) } else { ++i } } } 删除数组中索引i处的元素: 删除数组中索引i处的元素: array.splice(i, 1) 如果你想从数组中删除值为number的每个元素,可以这样做: for (let i = array.length - 1; i>

= 0; iMel -) {if (array [I] = number) {array.splice (I, 1)}} if you just want to make the cable

If you only want to make the element at index I no longer exist, but you don't want to change the index of other elements:

Delete array [i]

two。 How to redirect users from one page to another using jQuery or pure JS

JQuery is not required, _ window.location.replace (…) It is most suitable for simulating HTTP redirection. _ window.location.replace (...) It is better to use _ window.location.href because replace () does not keep the original page in the session history, which means that the user will not get caught in the never-ending fallback button.

If you want to simulate clicking a link, you can use location.href, and if you want to simulate HTTP redirection, use location.replace.

Examples:

/ / simulate HTTP redirection _ window.location.replace ("http://stackoverflow.com") / / Simulation Click Link _ window.location.href =" http://stackoverflow.com"

You can also do this:

$(location) .attr ('href',' http://stackoverflow.com')

How 3.JavaScript closures work

A closure is a function and a reference to the function's external scope (lexical context), which is part of each execution context (stack) and is a mapping between identifiers (that is, local variable names) and values.

Each function in JavaScript maintains a reference to its external lexical environment. This reference is used to configure the execution context created when the function is called. Whenever a function is called, this reference enables code within the function to view variables declared outside the function.

In the following code, inner forms a closure with the lexical environment of the execution context created when foo is called, and the variable secret is hidden from the outside:

Function foo () {const secret = Math.trunc (Math.random () * 100) return function inner () {console.log (`The secret number is ${secret}. `)} const f = foo () / / the only way that secret cannot directly access f () / / from outside foo is to call f

In other words, in JavaScript, functions have references to the private state that only they (and any other function declared in the same lexical environment) can access. This state is invisible to the caller of the function, which provides an excellent mechanism for data hiding and encapsulation.

Remember that functions in JavaScript can be passed like variables, which means that pairs of functions and states can be passed in the program: similar to passing an instance of a class in C++.

If JavaScript does not have a closure, you must explicitly pass more state between functions, resulting in a longer parameter list and more redundant code.

So, if you want a function to always have access to private state, you can use a closure, and we often want to associate the state with the function. For example, in Java or C++, when you add private instance variables and methods to a class, this associates state with function.

In C and most other programming languages, after the function returns, all local variables are no longer accessible because the stack is destroyed. In JavaScript, if you declare a function in another function, the local variable of the external function can still be accessed after it is returned. In this way, in the above code, secret is still available inside the function object after returning from foo.

Closures are useful when you need a private state associated with a function. This is a very common scenario. JavaScript didn't have class syntax until 2015, it still doesn't have private field syntax, and closures meet this need.

Private instance variable

In the following example, the function toString hides some of the details of the Car class.

Function Car (manufacturer, model, year, color) {return {toString () {return `${manufacturer} ${model} (${year}, ${color})`}} const car = new Car ('Aston Martin','V8 Vantage','2012','Quantum Silver') console.log (car.toString ())

Functional programming

In the following code, the function inner hides fn and args.

Function curry (fn) {const args = [] return function inner (arg) {if (args.length = fn.length) return fn (... args) args.push (arg) return inner}} function add (a, b) {return a + b} const curriedAdd = curry (add) console.log (curriedAdd (2) (3) ()) / / 5

Event-oriented programming

In the following code, the function onClick hides the variable BACKGROUND_COLOR.

Const $= document.querySelector.bind (document) const BACKGROUND_COLOR = 'rgba' function onClick () {$('body'). Style.background = BACKGROUND_COLOR} $(' button'). AddEventListener ('click', onClick) Set background color

Modularization

In the following example, all implementation details are hidden in a function expression that executes immediately. The functions tick and toString hide private states and functions that need to do their job. Closures enable us to modularize and encapsulate our code.

Let namespace = {} (function foo (n) {let numbers = [] function format (n) {return Math.trunc (n)} function tick () {numbers.push (Math.random () * 100)} function toString () {return numbers.map (format)} n.counter = {tick, toString}} (namespace)) const counter = namespace.counter counter.tick () counter.tick () console.log (counter.toString ())

Example 1:

This example shows that local variables are not copied in the closure. The closure retains a reference to the original variable itself. It seems that the stack remains in memory even after the external function exits.

Function foo () {let x = 42 let inner = function () {console.log (x)} x = x + 1 return inner} let f = foo () f ()

Example 2:

In the following code, the three methods log, increment, and update are all in the same lexical environment closure.

Function createObject () {let x = 42; return {log () {console.log (x)}, increment () {x = value}} const o = createObject () o.increment () o.log () / / 43 o.update (5) o.log () / / 5 const p = createObject () p.log () / / 42

Example 3:

If you are using variables that are declared using var, it is important to note that variables declared with var are promoted. With the introduction of let and const, this is almost no problem in modern JavaScript.

In the following code, a new inner function is created in each loop, and the variable I is overridden, but because var raises I to the top of the function, all of these inner functions cover the same variable, which means that the final value of I (3) is printed three times.

Function foo () {var result = [] for (var I = 0; I

< 3; i++) { result.push(function inner () { console.log(i) }) } return result } const result = foo() for(var i = 0; i < 3; i++) { result[i]() } // 3 3 3 最后一点: 每当在JavaScript中声明函数时,都会创建一个闭包。 从一个函数内部返回另一个函数是闭包的经典例子,因为外部函数内部的状态对于返回的内部函数是隐式可用的,即使外部函数已经完成执行。 只要在函数内使用eval(),就会使用一个闭包。eval的文本可以引用函数的局部变量,在非严格模式下,甚至可以通过使用eval('var foo = ')创建新的局部变量。 当在函数内部使用new Function()(Function constructor)时,它不会覆盖其词法环境,而是覆盖全局上下文。新函数不能引用外部函数的局部变量。 在JavaScript中,闭包类似于在函数声明时保留对作用域的引用(而不是复制),后者又保留对其外部作用域的引用,以此类推,一直到作用域链顶端的全局对象。 声明函数时创建一个闭包。当调用函数时,此闭包用于配置执行上下文。 每次调用函数时都会创建一组新的局部变量。 JavaScript 中的每个函数都维护与其外部词法环境的链接。词法环境是所有名称的映射(例如,变量,参数)及其范围内的值。因此,只要看到function关键字,函数内部的代码就可以访问在函数外部声明的变量。 function foo(x) { var tmp = 3; function bar(y) { console.log(x + y + (++tmp)); // 16 } bar(10); } foo(2); 上面输出结果是16,参数x和变量tmp都存在于外部函数foo的词法环境中。函数bar及其与函数foo的词法环境的链接是一个闭包。 函数不必返回即可创建闭包。仅仅凭借其声明,每个函数都会在其封闭的词法环境中关闭,从而形成一个闭包。 function foo(x) { var tmp = 3; return function (y) { console.log(x + y + (++tmp)); // 16 } } var bar = foo(2); bar(10); // 16 bar(10); // 17 上面还是打印16,因为bar内的代码仍然可以引用参数x和变量tmp,即使它们不再直接的作用域内。 但是,由于tmp仍然在bar的闭包内部徘徊,因此可以对其进行递增。每次调用bar时,它将增加1。 闭包最简单的例子是这样的: var a = 10; function test() { console.log(a); // will output 10 console.log(b); // will output 6 } var b = 6; test(); 当调用一个JavaScript函数时,将创建一个新的执行上下文ec。连同函数参数和目标对象,这个执行上下文还接收到调用执行上下文的词法环境的链接,这意味着在外部词法环境中声明的变量(在上面的例子中,a和b)都可以从ec获得。 每个函数都会创建一个闭包,因为每个函数都有与其外部词法环境的链接。 注意,变量本身在闭包中是可见的,而不是副本。 4. use strict 在 JavaScript 中做了什么,背后的原因是什么 引用一些有趣的部分: 严格模式是ECMAScript 5中的一个新特性,它允许我们将程序或函数放置在严格的操作上下文中。这种严格的上下文会防止某些操作被执行,并引发更多异常。 严格模式在很多方面都有帮助: 它捕获了一些常见的编码漏洞,并抛出异常。 当采取相对不安全的操作(例如访问全局对象)时,它可以防止错误或抛出错误。 它禁用令人困惑或考虑不周到的特性。 另外,请注意,我信可以将"strict mode"应用于整个文件,也可以仅将其用于特定函数。 // Non-strict code... (function(){ "use strict"; // Define your library strictly... })(); // Non-strict code... 如果是在混合使用旧代码和新代码的情况,这可能会有所帮助。它有点像在Perl中使用的"use strict"。通过检测更多可能导致损坏的东西,帮助我们减少更多的错误。 现在所有主流浏览器都支持严格模式。 在原生ECMAScript模块(带有import和export语句)和ES6类中,严格模式始终是启用的,不能禁用。 5.如何检查字符串是否包含子字符串? ECMAScript 6 引入了string .prototype.include const string = "foo"; const substring = "oo"; console.log(string.includes(substring)); 不过,IE 不支持 includes。在 CMAScript 5或更早的环境中,使用String.prototype.indexOf。如果找不到子字符串,则返回-1: var string = "foo"; var substring = "oo"; console.log(string.indexOf(substring) !== -1); 为了使其在旧的浏览器中运行,可以使用这种polyfill: if (!String.prototype.includes) { String.prototype.includes = function(search, start) { 'use strict'; if (typeof start !== 'number') { start = 0; } if (start + search.length >

This.length) {return false;} else {return this.indexOf (search, start)! =-1;}};}

6. Var functionName = function () {} and function functionName () {}

The difference is that functionOne is a function expression, so it is defined only when this line is reached, while functionTwo is a function declaration defined when the function or script around it is executed (due to promotion).

For example, function expressions

/ / TypeError: functionOne is not a function functionOne (); var functionOne = function () {console.log ("Hello!");}

Function declaration:

/ / "Hello!" FunctionTwo (); function functionTwo () {console.log ("Hello!");}

In the past, the handling of function declarations defined in blocks was inconsistent between different browsers. Strict mode (introduced in ES5) solves this problem by limiting the scope of a function declaration to its closed block.

'use strict'; {/ / note this block! Function functionThree () {console.log ("Hello!");}} functionThree (); / / ReferenceError

Function abc () {} also has a scope-the name abc is defined in the scope where the definition is encountered. Example:

Function xyz () {function abc () {}; / / abc is defined here.} / /. It's not here.

If you want to alias the function on all browsers, you can do this:

Function abc () {}; var xyz = abc

In this case, xyz and abc are both aliases for the same object

Console.log (xyz = abc) / / true

Its name is automatically assigned. But when you define it,

Var abc = function () {}; console.log (abc.name); / / ""

Its name is called null, and we create an anonymous function and assign it to a variable. Another good reason to use a composite style is to use a short internal name to refer to yourself, while providing external users with a long, non-conflicting name:

/ / suppose really.long.external.scoped is {} really.long.external.scoped.name = function shortcut (n) {/ / it recursively calls itself: shortcut (n-1); / /. / / let it pass itself as a callback:: someFunction (shortcut); / /.}

In the above example, we could do the same for external names, but this is clumsy (and slower). Another way to reference yourself is arguments.callee, which is also relatively long and is not supported in strict mode.

In fact, JavaScript treats the two statements differently. Here is a function declaration:

Function abc () {}

The abc here can be defined anywhere in the current scope:

/ / We can call abc () here; / / define function abc () {} / / or we can call abc () here.

In addition, despite the return statement, it is possible to promote:

/ / We can call abc (); return; function abc () {} here

Here is a function expression:

Var xyz = function () {}

The xyz here is defined from the assignment point:

/ / We cannot call xyz () here; / / define xyz xyz = function () {} / / We can call xyz () here.

The real reason for the difference between a function declaration and a function expression.

Var xyz = function abc () {}; console.log (xyz.name); / / "abc"

Personally, we prefer to use function expression declarations because this controls visibility. When we define a function like this:

Var abc = function () {}

We know that if we don't define abc anywhere in the scope chain, then we define it in the global scope. Even if used within eval (), the definition of this type is flexible. And the definition:

Function abc () {}

Depends on the context and may make you guess where it is actually defined, especially in the case of eval ()-depends on the browser.

7. How do I delete a property from a JavaScript object?

We can delete the properties of the object as follows:

Delete myObject.regex; / / or delete myObject ['regex']; / / or var prop = "regex"; delete myObject [prop]

Examples:

Var myObject = {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^ http://.*"}; delete myObject.regex; console.log (myObject)

Objects in JavaScript can be thought of as mappings between keys and values. The delete operator is used to delete one key at a time (often referred to as an object property).

Var obj = {myProperty: 1} console.log (obj.hasOwnProperty ('myProperty')) / / true delete obj.myProperty console.log (obj.hasOwnProperty (' myProperty')) / / false

Instead of freeing memory directly, the delete operator removes the property itself from the object, rather than simply assigning a null or undefined value to the property.

Note that if the value of the deleted property is a reference type (object) and another part of the program still holds a reference to that object, then the object is certainly not garbage collected until all references to it disappear.

Delete is valid only for attributes whose descriptor is marked configurable.

8. Which equal operator (= = vs =) should be used in JS comparisons?

The strict equality operator (= =) behaves the same as the abstract equality operator (= =) unless there is no type conversion and the type must be the same to be considered equal.

The = = operator compares equality after type conversion. The = = operator is not converted, so if the two values are of different types, then = = only returns false.

JavaScript has two sets of equality operators: = = and! = and their twin brothers = = and! =. If the two operands have the same type and the same value, then the result of = = is true, and the result of! = = is false.

Here are some examples:

'' = ='0' / / false 0 = ='/ / true 0 = ='0' / / true false = = 'false' / / false false = =' 0' / / true false = = undefined / / false false = = null / / false null = = undefined / / true'\ t\ r\ n'= = 0 / / true

Some of the above will look confusing, so try to use the strict comparison operator (=). For reference types, the = and = = operations are consistent (except in special cases).

Var a = [1je 2jue 3]; var b = [1je 2pai 3]; var c = {x: 1, y: 2}; var d = {x: 1, y: 2}; var e = "text"; var f = "te" + "xt" A = = b / / false a = = b / / false c = = d / / false c = d / / false e = = f / / true e = f / / true

In a special case, when you compare a literal amount of a string to a string object, the value of the object is the same as the value of the literal quantity of the phase because of the object's toString or valueOf method.

Consider comparing the literal amount of a string to a string object created by the String constructor:

"abc" = = new String ("abc") / / true "abc" = = new String ("abc") / / false

Here, the = = operator checks the values of the two objects and returns true, but the = sees that they are not of the same type and returns false. Which one is right? It depends on what you want to compare.

Our advice is to bypass the problem altogether, just don't use the String constructor to create a string object.

Use the = = operator (equal to)

True = = 1; / / true, because true is converted to 1, and then compare "2" = = 2; / / true, because "2" is converted to 2, and then compare

Use the = operator

True = 1; / / false "2" = 2; / / false

9. What is the most effective way to make a deep copy of an object in JavaScript?

Fast cloning, data loss-JSON.parse/stringify

If you do not use Date, function, undefined, Infinity, RegExp, Map, Set, blob, sparse array, typed array, or other complex type in an object, you can use a single line of simple code to deeply copy an object:

JSON.parse (JSON.stringify (object)) const a = {string: 'string', number: 123, bool: false, nul: null, date: new Date (), undef: undefined, / / lost inf: Infinity, / / set to null re: /. * /, / / lost} console.log (a); console.log (typeof a.date); / / object const clone = JSON.parse (JSON.stringify (a)); console.log (clone) / * object {string: 'string', number:' string', number: 123, bool: false, nul: null, date: '2020-09-04T00Partition 45purl 41.823Z, inf: null, re: {}} * / console.log (typeof clone.date); / / string

Use the library for reliable cloning

Because cloning objects is not a simple task (complex types, circular references, functions, and so on), most major libraries provide functions to copy objects. If you are already using a library, check to see if it has object cloning capabilities. For example

Lodash-cloneDeep; can be imported separately through the lodash.clonedeep module, and if you have not yet used a library that provides deep copy functionality, it may be your best choice

AngularJS-angular.copy

JQuery-jQuery.extend (true, {}, oldObject); .clone () Clones only DOM elements

ES6

ES6 provides two shallow copy mechanisms: Object.assign () and spread syntax. It copies the values of all enumerable own properties from one object to another. For example

Var A1 = {a: "2"}; var A2 = Object.assign ({}, A1); var A3 = {... A1}; / / Spread Syntax

In previous tests, speed was the main problem

JSON.parse (JSON.stringify (obj))

This is the slowest way to make a deep copy of an object, and it is 10-20% slower than jQuery.extend.

When the deep flag is set to false (shallow cloning), jQuery.extend is very fast. This is a good choice because it includes some extra logic for type validation and does not copy undefined properties, etc., but it also slows you down.

If you want to copy an object and you know the object structure. Then, you can write a simple for (var i in obj) loop to clone your objects and check hasOwnProperty, which will be much faster than jQuery.

Var clonedObject = {knownProp: obj.knownProp,.. }

Note the use of the JSON.parse (JSON.stringify (obj)) method on the Date object JSON. JSON.stringify (new Date ()) returns a string representation of the date in ISO format, and JSON.parse () does not convert it back to the Date object.

10. How do I include a JavaScript file in another JavaScript file?

Older versions of JavaScript do not have import, include, or require, so many different approaches have been developed to address this problem.

But starting in 2015 (ES6), JavaScript already has an ES6 module standard that allows modules to be imported into Node. For compatibility with older browsers, build tools such as Webpack and Rollup and / or compilation tools such as Babel can be used.

ES6 Module

Since v8.5, Node.js has supported the ECMAScript (ES6) module with the-- experimental-modules flag, and at least Node.js v13.8.0 does not have this flag. To enable ESM (as opposed to commonjs-style modular systems before Node.js [CJS]), you can use "type": "module" in package.json. Or provide the file with the extension .mjs. (similarly, if the default is ESM, modules written with previous CJS modules from Node.js can be named .cjs.)

Use package.json:

{"type": "module"}

In module.js:

Export function hello () {return "Hello";}

Main.js:

Import {hello} from'. / module.js'; let val = hello (); / / val is "Hello"

Using .mjs, there will be a corresponding module.mjs:

Export function hello () {return "Hello";}

In main.mjs

Import {hello} from'. / module.mjs'; let val = hello (); / / val is "Hello"

Since Safari 10.1, Chrome 61, Firefox 60 and Edge 16, browsers have supported loading ECMAScript modules directly (no tools like Webpack are needed). There is no need to use the .mjs extension of Node.js; the browser completely ignores the file extension on the module / script.

Import {hello} from'. / hello.mjs'; / / Or it could be simply `hello.js` hello ('world'); / / hello.mjs-- or it could be simply `hello.js` export function hello (text) {const div = document.createElement (' div'); div.textContent = `Hello ${text} `; document.body.appendChild (div);}

Dynamic import in browser

Dynamic import allows scripts to load other scripts as needed

Import ('hello.mjs') .then (module = > {module.hello (' world');})

Node.js require

Module.exports/require is more commonly used in Node.js.

/ / mymodule.js module.exports = {hello: function () {return "Hello";}}

/ / server.js const myModule = require ('. / mymodule'); let val = myModule.hello (); / / val is "Hello"

Dynamically load a file

We can dynamically import files by creating script dynamically:

Function dynamicallyLoadScript (url) {var script = document.createElement ("script"); document.head.appendChild (script);}

Detect when the script is executed

Now, there are big problems. The above dynamic loading is performed asynchronously, which can improve the performance of the web page. This means that the resource cannot be used immediately after dynamic loading, as it may still be loaded.

For example, my_lovely_script.js contains MySuperObject:

Var js = document.createElement ("script"); js.type = "text/javascript"; js.src = jsFilePath; document.body.appendChild (js); var s = new MySuperObject (); Error: MySuperObject is undefined

Then, press F5 to reload the page, which may be effective. So what should we do?

We can use callback functions to solve some problems.

Function loadScript (url, callback) {var head = document.head; var script = document.createElement ('script'); script.type =' text/javascript'; script.src = url; script.onload = callback; head.appendChild (script);}

Then write the code to use after loading the script in the lambda function

Var myPrettyCode = function () {/ / Here, do whatever you want}

Then, run the code:

LoadScript ("my_lovely_script.js", myPrettyCode)

Note that the script may be executed after or before the DOM is loaded, depending on the browser and whether the line script.async = false; is included.

Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report