这篇文章涵盖了JavaScript的一些基本概念。每个JavaScript程序员都必须了解并掌握这些知识。
1. JavaScript原型
让我解释一下用JavaScript创建对象的各种方法。在JavaScript中创建对象的方法之一是构造函数。考虑下面的构造函数:
function Bike(model,color){
this.model = model,
this.color = color,
this.getDetails = function(){
return this.model+' bike is '+this.color;
}
}
var bikeObj1 = new Bike('BMW','BLACK');
var bikeObj2 = new Bike('BMW','WHITE');
console.log(bikeObj1.getDetails()); //output: BMW bike is BLACK
console.log(bikeObj2.getDetails()); //output: BMW bike is WHITE
在上面的示例中,我们使用构造函数创建了两个对象bikeObj1,bicycleObj2。在JavaScript中,每个对象都有其自己的方法和属性。在我们的示例中,两个对象具有构造函数的两个实例getDetails()。复制getDetails做同样的事情是没有意义的。
相对于拷贝一份, 我们将使用一个构造函数的原型属性.
Prototype
使用JavaScript创建对象时,JavaScript引擎会将proto属性添加到新创建的对象,称为dunder proto。dunder proto或proto指向构造函数的原型对象。
function Bike(model,color){
this.model = model,
this.color = color
}
Bike.prototype.getDetails = function(){
return this.model+" bike is "+this.color;
}
var bikeObj1 = new Bike(‘BMW’,’Black’);
console.log(bikeObj1.getDetails());
bikeObj1使用Bike构造函数创建的对象具有dunder proto或proto属性,它指向构造函数的原型对象Bike。
在下面的代码,无论bikeObj1 它是dunder proto或proto. property和Bike.prototype 财产相等。让我们使用===运算符检查它们是否指向相同的位置
console.log(bikeObj1.__proto__ === Bike.prototype );
//output : true
因此,使用原型属性,创建了多少个对象的函数仅一次加载到内存中,如果需要,我们可以覆盖函数。
2. JavaScript(ES6)类
ES6中引入的JavaScript类主要是对JavaScript现有的基于原型的继承的语法糖。类语法不会向JavaScript引入新的面向对象的继承模型。在早期的ES5中使用函数表达式。
现有基于原型的继承:
function Bike(model,color) {
this.model = model;
this.color = color;
}
Bike.prototype.getInfo = function() {
return this.color + ' ' + this.model+ ' bike';
};
定义类:
实际上,类是“特殊函数”,就像您可以定义函数表达式和函数声明一样,类语法具有两个组成部分:类表达式和类声明。
ES6 class:
class Bike{
constructor(color, model) {
this.color= color;
this.model= model;
}
}
使用class的好处
- 方便,自成体系的语法。
- 在JavaScript中模拟类的单一规范方法。在ES6之前,流行的库中有几种竞争的实现。
- 来自基于class的语言背景的人们更加熟悉。
- IIFE (立即调用函数表达式)
什么是JavaScript中的IIFE?
IIFE(立即调用函数表达式)是一个JavaScript 函数,它在定义后立即运行。
(function ()
{// logic here })
();
您的初次见面可能看起来很混乱,但是实际上,这种模式很简单。该模式将立即调用函数表达式。
JavaScript函数可以通过函数声明或函数表达式来创建。函数声明是创建命名函数的“常规”方法。
在表达式的上下文中创建的函数也是函数表达式。JavaScript表达式的关键在于它们返回值。
在以上两种情况下,表达式的返回值都是函数。
这意味着,如果我们想立即调用函数表达式,则只需要在最后加上几个括号即可。这使我们回到了前面的代码中:
(function ()
{ var foo = “hello”;
console.log(foo);
})
();
console.log(foo); //Error: foo is not defined
使用IIFE的主要原因是获得数据隐私。因为JavaScript的var将变量作用域限定为其包含的函数,所以IIFE中声明的任何变量都不能被外界访问。
4.作用域:
JavaScript作用域的简单定义:
作用域是运行时在代码某些特定部分中变量,函数和对象的可访问性。换句话说,范围决定了代码区域中变量和其他资源的可见性。
按照上面对Scope的定义,限制点的可见性在于代码中没有处处可用的所有内容。
Scope主要通过两种方式定义:
- 全局作用域
- 局部作用域
var greeting='Welcome to blog';
(function(){
console.log(greeting); //Output: Welcome to blog
})();
考虑上面的代码greeting变量应该是全局范围的,它可以在函数内部访问,
(function(){
var greeting = 'Welcome to blog';
console.log(greeting); //Output: Welcome to blog
})();
console.log(greeting); //Output:Reference-Error greeting not defined
在上面的本地范围代码中,
JavaScript ES6中的作用域级别变量已更新了吊装变量let,var,const类型检查,为了学习作用域,还需要了解作用域前置
。
5. JavaScript闭包
什么是闭包?
闭包是一个函数和在其内被宣布该函数的词法环境的组合
闭包是一个内部函数,可以访问外部(封装)函数的变量-作用域链。闭包具有三个作用域链:它可以访问自己的范围(在大括号之间定义的变量),可以访问外部函数的变量,并且可以访问全局变量。
让我们在下面看到一个关闭示例:
function User(name){
var displayName = function(greeting){
console.log(greeting+' '+name);
}
return displayName;
}
var myFunc = User('Raj');
myFunc('Welcome '); //Output: Welcome Raj
myFunc('Hello '); //output: Hello Raj
在这段代码中,我们有一个外部函数User(),它返回一个内部函数为displayName(),
即使在返回外部函数之后,内部函数也可以访问外部函数范围内的变量。
6.模块模式
在JavaScript中,模块是一小部分独立的可重用代码。模块是许多JavaScript设计模式的基础,并且在构建任何非平凡的基于JavaScript的应用程序时至关重要。
JavaScript模块导出为值而不是定义类型,因为JavaScript模块可以导出对象,导出包含HTML模板或CSS样式表的字符串的模块也是常见的。
JavaScript没有私有关键字,但是我们可以使用闭包来实现私有方法和属性。
var myModule = (function() {
'use strict';
var _privateProperty = 'Hello World';
function _privateMethod() {
console.log(_privateProperty);
}
return {
publicMethod: function() {
_privateMethod();
}
};
}());
myModule.publicMethod(); // outputs 'Hello World'
console.log(myModule._privateProperty); // is undefined
protected by the module closure
myModule._privateMethod(); // is TypeError protected by the module closure
这些模块可以使用export关键字导出到其他JS文件,
//myMOdule.js file
export default myModule;
模块可以导入到另一个JS文件
//second.js file
import myModule from ‘./myModule’;
为什么我们需要使用模块?
使用模块有利于扩展,这有很多好处,
- 可维护性
- 可重用性
- 命名空间
7. Hoisting 作用域提升:
作用域提升是一种JavaScript机制,在执行代码之前,变量和函数声明会移至其作用域的顶部。
在简单的代码说明作用域提升
console.log(Hoist);
var Hoist = ’The variable Has been hoisted’;
//output : undefined//
实际上,JavaScript提升了变量声明。这就是上面的代码对解释器的外观
var Hoist;
console.log(Hoist);
Hoist = ’The variable Has been hoisted’;
JavaScript仅提升声明,而不初始化。
不可避免地,这意味着无论在何处声明函数和变量,无论它们的作用域是全局的还是局部的,它们都将移至其作用域的顶部。
关于变量提升,他可以提升
- JavaScript(ES6)中的let,var,const关键字
- 函数function提升
- 类class提升
8. Currying 柯里化
Currying是一种将具有多个参数的函数评估为具有单个参数的函数序列的技术。
换句话说,当一个函数而不是一次使用所有参数时,采用第一个参数并返回一个采用第二个参数的新函数,并返回采用第三个参数的新函数,依此类推,直到所有参数都被接受为止。实现。
考虑下面的示例代码:
var add = function (a){
return function(b){
return function(c){
return a+b+c;
}
}
}
console.log(add(2)(3)(4)); //output 9
console.log(add(3)(4)(5)); //output 12
这是通过闭包实现的,因此程序变量a,b上面的父函数的私有属性
为什么有用的curring?
主要它有助于创建高阶函数。这在事件处理中非常有帮助。
参考
15 JavaScript concepts that every JavaScript Programmer must know
网友评论