JavaScript知识点总结
Posted maydaytime
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript知识点总结相关的知识,希望对你有一定的参考价值。
javascript 是一种面向对象的动态语言,它包含类型、运算符、标准内置( built-in)对象和方法。它的语法来源于 Java 和 C,所以这两种语言的许多语法特性同样适用于 JavaScript。需要注意的一个主要区别是 JavaScript 不支持类,类这一概念在 JavaScript 通过对象原型(object prototype)得到延续(有关 ES6 类的内容参考这里Classes
)。另一个主要区别是 JavaScript 中的函数也是对象,JavaScript 允许函数在包含可执行代码的同时,能像其他对象一样被传递。
Number
(数字)String
(字符串)Boolean
(布尔)Symbol
(符号)(第六版新增)Object
(对象)Function
(函数)Array
(数组)Date
(日期)Math
(数学对象)RegExp
(正则表达式)Null
(空)Undefined
(未定义)Error
(错误)类型
parseInt("010", 10); //10
parseInt("010"); // 8 如果没有第二个参数,那么以0开头就是八进制 0x开头就是16进制
parseInt("0x10"); // 16
如何把二进制转为整数值?
parseInt("10011",2);
当第一个参数不是数字型字符串
parseInt("hello", 10); // NaN
NaN是一个特殊值 用它与任何数字计算 结果都是NaN
"hello".charAt(0); // "h"
"hello, world".replace("hello", "goodbye"); // "goodbye, world"
"hello".toUpperCase(); // "HELLO"
"hello".length; // 5
三、其他类型(null 和 undefined)
null的本质是一个空值,必须使用null关键字才能访问
undefined是一个未定义类型的对象(也是一个对象),它表示一个未初始化的值,也就是还没有被分配值。(JavaScript允许声明变量但不对其赋值,一个未被赋值的变量就是undefined类型)
布尔型:(true / false)其他类型对其转化
flase,0,"",NaN,null,undefined都会在JavaScript需要一个布尔值变量的时候隐式转换为false (其他的都会转化为true)
四、变量
在JavaScript中声明一个变量用var
var a; var name = "simon";
在JavaScript中的语句块中 是没有作用域的
五、运算符
JavaScript的算术操作符包括 +
、-
、*
、/
和 % ——
求余(与模运算不同)。赋值使用 =
运算符,此外还有一些复合运算符,如 +=
和 -=
,它们等价于 x = x op y
。
+可以用来连接字符串
"3" + 4 + 5; // 345 3 + 4 + "5"; // 75 1 === true; //false 123 === "123"; // false 123 == "123" // true 1 == true; // true
六、控制结构
if()...else if()...else() while() do...while() for( ; ; )/for( : )
- 短路与:var name = o && o.getName();
- 短路或:var name = otherName || "default";
- 三元运算符:var allowed = (age > 18) ? "yes" : "no";
- 多重分支时可以使用
基于一个数字或字符串的switch
语句:(在 switch
的表达式和 case
的表达式是使用 ===
严格相等运算符进行比较的:)
switch(action) { case ‘draw‘: drawIt(); break; case ‘eat‘: eatIt(); break; default: doNothing(); }
switch(1 + 3){ case 2 + 2: yay(); break; default: neverhappens(); }
七、对象
对象的创建方式:
1.var obj = new Object();
2.var obj = {} --->对象字面量
var obj = { name:"carrot", "for":"Max", details:{ color:"orange", size:12 }
- 可以用链式访问:
- 可以用中括号访问:
function Person(name,age){ this.name = name; this.age = age; }
var You = new Person("zhangjiahao","23");
可用You.name="ZJH"来赋值
obj["name"] = "Simon";
可用var name = You.name;来取值
var name = obj["name"];
中括号的方式的优点:中括号内都是字符串,所以可以用于运行时计算,且可以使用关键字,但在后期被解释时无法优化。
obj.for = "Simon"; // 语法错误,因为 for 是一个预留关键字 obj["for"] = "Simon"; // 工作正常
八、数组
JavaScript中的数组是一个特殊的对象。
与普通对象的区别在于,对于数组中的‘属性’(元素)只能通过中括号来访问。同时数组比普通对象多了一个length属性,该属性值始终比最大索引大一(并非等于数组中的元素个数)
数组的创建:
var a = [‘dog‘,‘cat‘,‘hen‘]; //数组字面量 var b = new Array(‘dog‘,‘cat‘,‘hen‘); //传统方式
如果访问了一个不存在的数组索引 会得到undefined
数组的遍历:
for(var i=0;i<a.length;i++) //传统方法--->不推荐,每次循环都会计算length,效率不高 for(var i=0,len = a.length;i<len;i++ ) //改进方法--->先循环开始前,先缓存a.length for(var i=0,item;item=a[i++]) //有局限,每次循环都会判断item是否空值或是否定义(是否为真)但是在数组内容中出现假值 会影响循环 for(var i in a) //这种循环 不单单会遍历出元素 ,也会遍历出自定义添加的array属性(向 Array.prototype添加了新的属性)
九、函数
对JavaScript的学习最重要的就是对象和函数两个部分。(函数也是对象)
函数:
function add(x,y){ var total = x + y; return total; }
var avg = function() { var sum = 0; for (var i = 0, j = arguments.length; i < j; i++) { sum += arguments[i]; } return sum / arguments.length; };
闭包:
var a = 1; var b = 2; (function() { var b = 3; a += b; })(); a; // 4 b; // 2
递归:
function countChars(elm) { if (elm.nodeType == 3) { // 文本节点 return elm.nodeValue.length; } var count = 0; for (var i = 0, child; child = elm.childNodes[i]; i++) { count += countChars(child); } return count; }
闭包递归:
var charsInBody = (function counter(elm) { if (elm.nodeType == 3) { // 文本节点 return elm.nodeValue.length; } var count = 0; for (var i = 0, child; child = elm.childNodes[i]; i++) { count += counter(child); } return count; })(document.body);
如上所提供的函数表达式的名称的作用域仅仅是该函数自身。这允许引擎去做更多的优化,并且这种实现更可读、友好。该名称也显示在调试器和一些堆栈跟踪中,节省了调试时的时间。
ps:需要注意的是 JavaScript 函数是它们本身的对象——就和 JavaScript 其他一切一样——你可以给它们添加属性或者更改它们的属性,这与前面的对象部分一样。
十、自定义对象
首先我们了解一些面向对象的基本概念和知识。
JavaScript
命名空间:注意:需要认识到重要的一点是:与其他面向对象编程语言不同的是,Javascript中的普通对象和命名空间在语言层面上没有区别。这点可能会让JavaScript初学者感到迷惑。
var MYAPP = MYAPP || {}; //全局命名空间 MYAPP.event = {}; //子命名空间
下面是用于创建命名空间和添加变量,函数和方法的代码写法:
//给普通方法和属性创建一个命名空间 MYAPP.commonMethod = { regExForName = "", regExForPhone = "", validateName = function(name){ //对参数name做一些操作 }, validatePhoneNo = function(phoneNo){ //对参数phoneNo做一些操作 } } MYAPP.event = { addListener = function(el , type , fn){ //code } removeListener = function(el , type , fn){ //code } } //使用addListner方法的写法 MYAPP.event.addListener("yourel" , "type" , callback)
function Person(){} //或 var Person = function(){}
function Person(){} var person1 = new Person(); var person2 = new Person();
function Person() { alert(‘Person instantiated‘); } var person1 = new Person(); var person2 = new Person();
function Person(name){ this.name = name; alert("this is my name" + this.name); } var person1 = new Person("Alice"); var person2 = new Person("Bob");
function Person(name){ this.name = name; } Person.protopype.sayHello = function(){ alert("hello,i‘m" + this.name); } var person1 = new Person("Alice"); var person2 = new Person("Bob"); person1.sayHello();
在JavaScript中方法通常是绑定到一个对象中的普通函数,所以我们也可以在访问域之外对其调用访问。
function Person(name){ this.name = name; } Person.protopype.sayHello = function(){ alert("hello,i‘m" + this.name); } var person1 = new Person("Alice"); var person2 = new Person("Bob"); person1.sayHello(); //Alice var helloFunction = person1.sayHello; helloFunction(); //undefined console.log(helloFunction === person1.sayHello); // logs true console.log(helloFunction === Person.prototype.sayHello); // logs true helloFunction.call(person1);
function Person(name){ this.name = name; } Person.prototype.walk = function(){ alert("i‘m walking!"); } Person.prototype.sayHello = function(){ alert("Hello , I‘m" + this.name ); } //定义Student构造器 function Student(name , subject){ Person.call(this , name);//这里也可以用apply(),详细见总结末端 this.subject = subject; } //建立一个由Person.prototype继承而来的Student.prototype对象 // 注意: 常见的错误是使用 "new Person()"来建立Student.prototype. // 这样做的错误之处有很多, 最重要的一点是我们在实例化时 // 不能赋予Person类任何的FirstName参数 // 调用Person的正确位置如下,我们从Student中来调用它 Student.prototype = Object.create(Person.prototype); //设置constructor 属性指向Student Student.prototype.constructor = Student; Student.prototype.sayHello = function(){ console.log("hello , I‘m" + this.name + "I‘m studying" + this.subject); } Student.prototype.sayGoodBye = function(){ alert("GOODBYE"); } // 测试实例: var student1 = new Student("Janet", "Applied Physics"); student1.sayHello(); // "Hello, I‘m Janet. I‘m studying Applied Physics." student1.walk(); // "I am walking!" student1.sayGoodBye(); // "Goodbye!" // Check that instanceof works correctly console.log(student1 instanceof Person); // true console.log(student1 instanceof Student); // true
在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。
抽象
抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承或者组合来实现。
JavaScript通过继承来实现具体化,通过让类的实例是其他对象的属性值来实现组合。
var foo = function(){}; console.log( ‘foo is a Function: ‘ + (foo instanceof Function) ); // logs "foo is a Function: true" cpnsole.log( ‘foo.prototype is an Object: ‘ + (foo.prototype instanceof Object) ); // logs "foo.prototype is an Object: true"
多态
就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。
---------------------------------------------------------------------------------
总结:
在经典面向对象中,对象指的是数据以及操作数据的集合。与C++ 和 Java 不同,JavaScript是一种基于原型的编程语言,没有Class语句,而是把函数作为类。
eg:(a)
function makePerson(first , last){ return { first : first, last : last } } function personFullName(person){ return person.first + " " + person.last; } function personFullNameReversed(person){ return person.last + " " + person.first; } person1 = makePerson("Kobe","Branyt"); personFullName(person1); personFullNameReversed(person1);
属于一个对象,那么不难得到:(b)
function makePerson(first , last){ return{ first : fitst, last : last, fullName : function(){ return this.first + ‘ ‘ this.last; } } } s = makerPerson(‘Kobe‘,‘Branty‘); s.fullName();// Kobe Branty
注意:this关键字, 当使用在函数中时,this指的是当前的对象,也就是调用该函数的对象。如果一个对象使用了.或者{}来访问其下的属性时,那么该对象就成了this。如果并不存在某个对象,那么此时this指向全局对象。
s = makePerson(‘Allen‘,‘Iverson‘); var fullName = s.fullName; fullName(); //undefined undefined
所以我们可以用this来改进上述makePerson函数:
function Person(first, last) { this.first = first; this.last = last; this.fullName = function() { return this.first + ‘ ‘ + this.last; } this.fullNameReversed = function() { return this.last + ‘, ‘ + this.first; } } var s = new Person("Simon", "Willison");
但此时创建一个Person对象的时候,我们都在其中创建了两个新的函数对象。所以我们可以将里面的函数拿出来:
function personFullName(person) { return this.first + ‘ ‘ + this.last; } function personFullNameReversed(person) { return this.last + ‘, ‘ + this.first; } function Person(first, last) { this.first = first; this.last = last; this.fullName = personFullName; this.fullNameReversed = personFullNameReversed; }
最好的方式:
function Person(first, last) { this.first = first; this.last = last; } Person.prototype.fullName = function() { return this.first + ‘ ‘ + this.last; } Person.prototype.fullNameReversed = function() { return this.last + ‘, ‘ + this.first; }
String
添加一个方法用来返回逆序的字符串:var s = "Simon"; s.reversed(); // TypeError on line 1: s.reversed is not a function String.prototype.reversed = function() { var r = ""; for (var i = this.length - 1; i >= 0; i--) { r += this[i]; } return r; } s.reversed(); // nomiS
原型组成链的一部分,那条链的根节点是Object.pototype,它包括toString()方法 --> 将对象转换成字符串调用的方法。这对于调用我们的Person对象很有用。
var s = new Person("Simon", "Willison"); s; // [object Object] Person.prototype.toString = function() { return ‘<Person: ‘ + this.fullName() + ‘>‘; } s.toString(); // <Person: Simon Willison>
ps:apply()和 call()
function trivialNew(constructor , ...args){ (...args是剩余参数2015新特性) var o = {};//创建一个新对象 constructor.apply(o,args); return o; }
apply()
有一个姐妹函数,名叫 call
,它也可以允许你设置 this
,但它带有一个扩展的参数列表而不是一个数组。
function lastName(){ return this.last.toUpperCase(); } var s = new Person("Simon","Willison"); lastName.call(s); //与下面效果一致 s.lastName = lastName; s.lastName();
内部函数
function betterExampleNeeded() { var a = 1; function oneMoreThanA() { return a + 1; } return oneMoreThanA(); }
function makeAdder(a){ return funtion(b){ return a+b; } } var x = makeAdder(5); var y = makeAdder(20); x(6);//11 y(7);//27
function leakMemory() { var el = document.getElementById(‘el‘); var o = { ‘el‘: el }; el.o = o; }
在 IE 中,每当在一个 JavaScript 对象和一个本地对象之间形成循环引用时,就会发生内存泄露。这段代码的循环引用会导致内存泄露:IE 不会释放被el
和 o
使用的内存,直到浏览器被彻底关闭并重启后。
以上是关于JavaScript知识点总结的主要内容,如果未能解决你的问题,请参考以下文章