회사 내부 기술 공유(JS 고급) 투표가 실패하여 JS에 대해 잘 모르는 아이들이 빨리 배우고 익힐 수 있도록 좋은 JS 소개 블로그 게시물을 먼저 번역하겠습니다. 이 마법의 언어.
JavaScript는 일반적으로 다음 작업을 처리하는 데 사용되는 객체 지향 동적 언어입니다.
웹 페이지 수정
HTML 및 CSS 생성
동적 HTML 콘텐츠 생성
특수 효과 생성
사용자 상호작용 인터페이스 제공
사용자 상호작용 구성요소 생성
사용자 확인 입력
자동 채우기 양식
http:/와 같은 로컬 또는 원격 데이터를 읽을 수 있는 프런트 엔드 애플리케이션 /m.sbmmt.com /
Nodejs를 통해 JAVA, C#, C++와 같은 서버측 프로그램 구현
다음을 포함한 분산 WEB 프로그램 구현 프론트엔드 및 서버사이드
현재 브라우저에서 지원하는 JavaScript 버전은 "ECMAScript 5.1" 또는 간단히 "ES5"라고 부르지만 다음 두 버전은 "ES6"이라고 합니다. 많은 추가 기능과 개선된 구문을 갖춘 "ES7"(또는 "ES2015" 및 "ES2016", 새 버전은 올해 이름을 따서 명명됨)은 매우 기대할만한 가치가 있습니다. 브라우저 및 백엔드 JS 환경 지원).
이 블로그 게시물은 "Building Front-End Web Apps with Plain JavaScript"라는 책에서 인용되었습니다.
JS에는 문자열, 숫자 및 부울의 3가지 값 유형이 있습니다. v 변수를 사용하여 typeof(v)와 비교하기 위해 다양한 유형의 값을 저장할 수 있습니다. 유형(동사)===”숫자”.
JS에는 Object, Array, Function, Date 및 RegExp의 5가지 참조 유형이 있습니다. 배열, 함수, 날짜, 정규식은 특수한 유형의 객체이지만 개념적으로 날짜와 정규식은 객체 형태로 패키징된 값 유형입니다.
변수, 배열, 함수 매개변수 및 반환 값은 선언할 필요가 없습니다. 일반적으로 JavaScript 엔진에서 확인하지 않으며 자동으로 유형이 변환됩니다.
변수 값은 다음과 같습니다.
문자열, 숫자, 부울과 같은 데이터
객체 참조: as 일반 객체 , 배열, 함수, 날짜, 정규 표현식
초기화된 객체 변수의 기본값으로 자주 사용되는 특수 값 null
정의되지 않은 특수값, 선언되었지만 초기화되지 않은 초기값
문자열은 유니코드 문자 시퀀스입니다. 문자열 상수는 "Hello World!", "A3F0′ 또는 빈 문자열 ""과 같이 작은따옴표나 큰따옴표로 묶입니다. 두 개의 문자열 표현식은 + 연산자를 사용하여 연결될 수 있으며, 같음으로 비교:
if (firstName + lastName === "James Bond")
문자열의 문자 수는 길이 속성을 통해 얻을 수 있습니다:
console.log( "Hello world!".length); // 12
모든 숫자 값은 64비트 부동 소수점<🎜입니다. > 단어 정수와 부동 소수점 숫자 사이에는 명확한 유형 구분이 없습니다. 숫자 상수가 숫자가 아닌 경우 해당 값은 isNaN 메서드를 사용하여 확인할 수 있는 NaN("숫자가 아님")으로 설정될 수 있습니다. , ES6까지는 숫자가 정수인지 테스트하는 데 사용된 Number.isInteger 메서드가 없었습니다. 따라서 아직 이를 지원하지 않는 브라우저에서는 숫자 값이 정수인지 또는 숫자 문자열인지 확인하는 데 사용되었습니다. 정수의 경우에는parseInt 함수를 사용해야 합니다. 마찬가지로 소수점 이하 자릿수를 포함하는 문자열은 숫자 n을 문자열로 변환하는 가장 좋은 방법은 Java와 마찬가지로
을 사용하는 것입니다. , 우리는 또한 두 개의 사전 정의된 부울 값(true 및 false)과 부울 값이 아닌 경우 !(not), &&(and), ||(or) 및 부울 값이 아닌 경우를 사용합니다. 값은 암시적으로 변환됩니다. 빈 문자열, 숫자 0 및 정의되지 않음 및 null은 false로 변환되고 다른 모든 값은 true로 변환됩니다. 일반적으로 등가 기호(=== 및)를 사용해야 합니다. !==) == 및 != 대신 숫자 2는 문자열 "2"와 같습니다. (2 == "2")는 true입니다. = new Array()는 빈 배열을 정의할 수 있습니다(Erhu: 전자를 권장함) VAR O ={} 및 var o = new Obejct()는 모두 빈 객체를 정의할 수 있습니다(Erhu: 전자는 여전히 유효합니다. 권장됨). 빈 객체 {}는 Object.prototype 상속 속성을 포함하므로 실제로 비어 있지 않습니다. 따라서 실제 빈 객체는 Null, var o = Object.create(null)로 프로토타입화되어야 합니다. 전역 범위 및 함수 범위, 블록 범위 없음 따라서 블록 내부의 변수 선언은 피해야 합니다function foo() { for (var i=0; i < 10; i++) { ... // do something with i } }
function foo() { var i=0; for (i=0; i < 10; i++) { ... // do something with i } }
从ES5开始,我们可以使用严格模式,获得更多的运行时错误检查。例如,在严格模式下,所有变量都必须进行声明。给未声明的变量赋值抛出异常。
我们可以通过键入下面的语句作为一个JavaScript文件或script元素中的第一行开启严格模式:’use strict’;
通常建议您使用严格模式,除非你的代码依赖于与严格的模式不兼容的库。
JS对象与传统的OO/UML对象不同。它们可以不通过类实例化而来。它们有属性、方法、键值对三种扩展。
JS对象可以直接通过JSON产生,而不用实例化一个类。
var person1 = { lastName:"Smith", firstName:"Tom"}; var o1 = Object.create( null); // an empty object with no slots
对象属性可以以两种方式获得:
使用点符号(如在C ++/ Java的):person1.lastName = “Smith”
使用MAP方式person1["lastName"] = “Smith”
JS对象有不同的使用方式。这里有五个例子:
记录,例如,var myRecord = {firstName:”Tom”, lastName:”Smith”, age:26}
MAP(也称为“关联数组”,“词典”或其他语言的“哈希表”)var numeral2number = {“one”:”1″, “two”:”2″, “three”:”3″}
非类型化对象
var person1 = { lastName: "Smith", firstName: "Tom", getFullName: function () { return this.firstName +" "+ this.lastName; } };
命名空间
var myApp = { model:{}, view:{}, ctrl:{} };
可以由一个全局变量形式来定义,它的名称代表一个命名空间前缀。例如,上面的对象变量提供了基于模型 – 视图 – 控制器(MVC)架构模式,我们有相应的MVC应用程序的三个部分。
可以用一个JavaScript数组文本进行初始化变量:
var a = [1,2,3];
因为它们是数组列表,JS数组可动态增长:我们可以使用比数组的长度更大的索引。例如,上面的数组变量初始化后,数组长度为3,但我们仍然可以操作第5个元素 a[4] = 7;
我们可以通过数组的length属性得到数组长度:
for (i=0; i < a.length; i++) { console.log(a[i]);} //1 2 3 undefined 7 `
我们可以通过 Array.isArray(a) 来检测一个变量是不是数组。
通过push方法给数组追加元素:a.push( newElement);
通过splice方法,删除指定位置的元素:a.splice( i, 1);
通过indexOf查找数组,返回位置或者-1:if (a.indexOf(v) > -1) …
通过for或者forEach(性能弱)遍历数组:
var i=0; for (i=0; i < a.length; i++) { console.log( a[i]); } a.forEach(function (elem) { console.log( elem); })
通过slice复制数组:var clone = a.slice(0);
map(也称为“散列映射”或“关联数组’)提供了从键及其相关值的映射。一个JS map的键是可以包含空格的字符串:
var myTranslation = { "my house": "mein Haus", "my boat": "mein Boot", "my horse": "mein Pferd" }
通过Object.keys(m)可以获得map中所有的键:
var i=0, key="", keys=[]; keys = Object.keys( myTranslation); for (i=0; i < keys.length; i++) { key = keys[i]; alert('The translation of '+ key +' is '+ myTranslation[key]); }
通过直接给不存在的键赋值来新增元素:
myTranslation["my car"] = "mein Auto";
通过delete删除元素:
delete myTranslation["my boat"];
通过in搜索map:
`if ("my bike" in myTranslation) ...`
通过for或者forEach(性能弱)和Object.keys()遍历map:
var i=0, key="", keys=[]; keys = Object.keys( m); for (i=0; i < keys.length; i++) { key = keys[i]; console.log( m[key]); } Object.keys( m).forEach( function (key) { console.log( m[key]); })
通过 JSON.stringify 将map序列化为JSON字符串,再JSON.parse将其反序列化为MAP对象 来实现复制:
var clone = JSON.parse( JSON.stringify( m))
请注意,如果map上只包含简单数据类型或(可能嵌套)数组/map,这种方法效果很好。在其他情况下,如果map包含Date对象,我们必须写我们自己的clone方法。
JS函数是特殊的JS的对象,它具有一个可选的名字属性和一个长度属性(参数的数目)。我们可以这样知道一个变量是不是一个函数:
if (typeof( v) === "function") {...}
JS函数可以保存在变量里、被当作参数传给其他函数,也可以被其他函数作为返回值返回。JS可以被看成一个函数式语言,函数在里面可以说是一等公民。
正常的定义函数方法是用一个函数表达式给一个变量赋值:
var myFunction = function theNameOfMyFunction () {...} function theNameOfMyFunction () {...}
其中函数名(theNameOfMyFunction)是可选的。如果省略它,其就是一个匿名函数。函数可以通过引用其的变量调用。在上述情况下,这意味着该函数通过myFunction()被调用,而不是通过theNameOfMyFunction()调用。
JS函数,可以嵌套内部函数。闭包机制允许在函数外部访问函数内部变量,并且创建闭包的函数会记住它们。
当执行一个函数时,我们可以通过使用内置的arguments参数,它类似一个参数数组,我们可以遍历它们,但由于它不是常规数组,forEach无法遍历它。arguments参数包含所有传递给函数的参数。我们可以这样定义一个不带参数的函数,并用任意数量的参数调用它,就像这样:
var sum = function () { var result = 0, i=0; for (i=0; i < arguments.length; i++) { result = result + arguments[i]; } return result; }; console.log( sum(0,1,1,2,3,5,8)); // 20
prototype原型链可以访问函数中的每一个元素,如Array.prototype.forEach(其中Array代表原型链中的数组的构造函数)。
var numbers = [1,2,3]; // create an instance of Array numbers.forEach( function (n) { console.log( n); });
我们还可以通过原型链中的prototype.call方法来处理:
var sum = function () { var result = 0; Array.prototype.forEach.call( arguments, function (n) { result = result + n; }); return result; };
Function.prototype.apply是Function.prototype.call的一个变种,其只能接受一个参数数组。
立即调用的JS函数表达式优于使用纯命名对象,它可以获得一个命名空间对象,并可以控制其变量和方法哪些可以外部访问,哪些不是。这种机制也是JS模块概念的基础。在下面的例子中,我们定义了一个应用程序,它对外暴露了指定的元素和方法:
myApp.model = function () { var appName = "My app's name"; var someNonExposedVariable = ...; function ModelClass1 () {...} function ModelClass2 () {...} function someNonExposedMethod (...) {...} return { appName: appName, ModelClass1: ModelClass1, ModelClass2: ModelClass2 } }(); // immediately invoked
这种模式在WebPlatform.org被当作最佳实践提及://m.sbmmt.com/
类是在面向对象编程的基础概念。对象由类实例化而来。一个类定义了与它创建的对象的属性和方法。
目前在JavaScript中没有明确的类的概念。JavaScript中定义类有很多不同的模式被提出,并在不同的框架中被使用。用于定义类的两个最常用的方法是:
构造函数法,它通过原型链方法来实现继承,通过new创建新对象。这是Mozilla的JavaScript指南中推荐的经典方法。
工厂方法:使用预定义的Object.create方法创建类的新实例。在这种方法中,基于构造函数继承必须通过另一种机制来代替。
当构建一个应用程序时,我们可以使用这两种方法创建类,这取决于应用程序的需求 。mODELcLASSjs是一个比较成熟的库用来实现工厂方法,它有许多优点。(基于构造的方法有一定的性能优势)
在ES6,用于定义基于构造函数的类的语法已推出(新的关键字类的构造函数,静态类和超类)。这种新的语法可以在三个步骤定义一个简单的类。
基类Person 定义了两个属性firstName 和lastName,以及实例方法toString和静态方法checkLastName:
class Person { constructor( first, last) { this.firstName = first; this.lastName = last; } toString() { return this.firstName + " " + this.lastName; } static checkLastName( ln) { if (typeof(ln)!=="string" || ln.trim()==="") { console.log("Error: " + "invalid last name!"); } } }
类的静态属性如下定义:
Person.instances = {};
一个子类定义的附加属性和可能会覆盖超类的方法:
class Student extends Person { constructor( first, last, studNo) { super.constructor( first, last); this.studNo = studNo; } // method overrides superclass method toString() { return super.toString() + "(" + this.studNo +")"; } }
在ES5,我们可以以构造函数的形式定义一个基于构造函数的类结构,下面是Mozilla的JavaScript指南中推荐的编码模式。此模式需要七个步骤来定义一个简单的类结构。由于这种复杂的模式可能很难记住,我们可能需要使用cLASSjs之类的库来帮助我们。
首先定义构造函数是隐式创建一个新的对象,并赋予它相应的值:
function Person( first, last) { this.firstName = first; this.lastName = last; }
这里的this指向新创建的对象。
在原型中定义实例方法:
Person.prototype.toString = function () { return this.firstName + " " + this.lastName; }
可以在构造函数中定义静态方法,也可以用.直接定义:
Person.checkLastName = function (ln) { if (typeof(ln)!=="string" || ln.trim()==="") { console.log("Error: invalid last name!"); } }
定义静态属性:
Person.instances = {};
定义子类并增加属性:
function Student( first, last, studNo) { // invoke superclass constructor Person.call( this, first, last); // define and assign additional properties this.studNo = studNo; }
通过Person.call( this, …) 来调用基类的构造函数。
将子类的原型链改为基类的原型链,以实现实例方法的继承(构造函数得改回来):
// Student inherits from Person Student.prototype = Object.create( Person.prototype); // adjust the subtype's constructor property Student.prototype.constructor = Student;
通过Object.create( Person.prototype) 我们基于 Person.prototype创建了一个新的对象原型。
定义覆盖基类方法的子类方法:
Student.prototype.toString = function () { return Person.prototype.toString.call( this) + "(" + this.studNo + ")"; };
最后通过new关键字来实例化一个类
var pers1 = new Person("Tom","Smith");
prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。
__proto__是一个对象拥有的内置属性(prototype是函数的内置属性。__proto__是对象的内置属性),是JS内部使用寻找原型链的属性。
每个对象都有个constructor属性,其指向的是创建当前对象的构造函数。
在这种方法中,我们定义了一个JS对象Person,并在其内部定义了一个create方法用来调用Object.create来创建类。
var Person = { name: "Person", properties: { firstName: {range:"NonEmptyString", label:"First name", writable: true, enumerable: true}, lastName: {range:"NonEmptyString", label:"Last name", writable: true, enumerable: true} }, methods: { getFullName: function () { return this.firstName +" "+ this.lastName; } }, create: function (slots) { // create object var obj = Object.create( this.methods, this.properties); // add special property for *direct type* of object Object.defineProperty( obj, "type", {value: this, writable: false, enumerable: true}); // initialize object Object.keys( slots).forEach( function (prop) { if (prop in this.properties) obj[prop] = slots[prop]; }) return obj; } };
这样,我们就有了一个Person的工厂类,通过调用create方法来实例化对象。
var pers1 = Person.create( {firstName:"Tom", lastName:"Smith"});
위 내용은 10분 안에 JavaScript를 시작하는 방법에 대해 자세히 설명합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!