1、JavaScript特色javascript
变量声明php
1 var arr = [1,2,3]; 2 var num = 123; 3 var steing = "abc";
1 var num = 123; 2 var num; 3 num = 123;
1 var num1 = 123, 2 num2 = 234, 3 num3 = 456;
2.变量命名规则css
3.数据类型(值类型)html
4.默认为false的值java
1 console.log(typeof(123)); // Number
2.Number(mix)[混合]es6
3.parseInt(string,radix)[基数]shell
1 parseInt('123abc123') // 123; 2 parseInt('abc123') // NaN; 3 parseInt('123') // 123; 4 parseInt('true') // NaN;
1 var demo = 10; 2 parseInt(demo,16) //16
4.parseFloat(radix)数组
1 parseFloat('123.2.3') // 123.2 2 parseFloat('132.2abc') // 123.2 3 parseFloat('123.abc1') // 123
5.toString(radix)浏览器
1 var demo = 123; 2 typeof demo.toString(); // string123; 3 typeof true.toString(); // stringtrue;
1 var dome = 10; 2 demo.toString(16) // A
6.String(mix)闭包
7.Boolean(mix)
1.isNaN()
2.算数运算符
3.逻辑运算符
4.不发生类型转换的比较运算符
函数声明提高:函数声明提高是一种总体提高,他、它会把函数声明和函数体一块儿提到前面。
变量声明提高:变量声明提高是一种局部提高,它仅仅将变量的声明提早了,可是并无将赋值一块儿提高。
1.js运行三部曲
2.预编译前奏
3.预编译四步
1 function test (a,b) { 2 console.log(a) 3 function a () {} 4 a = 222; 5 console.log(a) 6 function b () {}; 7 console.log(b) 8 var b = 111; 9 var a; 10 } 11 test(1);
1.函数声明有3种方式
1 var demo = function () {}; 函数表达式 2 function demo () {}; 函数声明 3 var demo = function xxx () {};命名函数表达式 //没用
1 function test(a,b) { 2 console.log(a + b); 3 return; 4 console.log('hello'); 5 } 6 test(1,2); // 打印结果3 不会打印hello
1 var demo = 123; // 全局变量 2 function test () { 3 var demo = 234; // 局部变量 4 console.log(demo); 5 var demo1 = 'hello'; 6 } 7 test(demo); // 打印234 就近打印局部变量,没有局部变量打印全局变量 8 console.log(demo1); // 报错 咱们的全局做用域没法访问局部做用域
1 function demo () { 2 var dome_a = 1; 3 function test () { 4 var demo_a = 2; 5 console.log(demo_a); 6 } 7 test(); 8 } 9 demo();
1.什么是闭包
1 function a (){ 2 var dome1 = 123; 3 add = function(){ 4 demo1 ++; 5 } 6 return function(){ 7 console.log(demo1); 8 }; 9 } 10 var demo = a (); 11 demo(); // 123 12 add(); 13 demo(); // 124
2.使用闭包的注意点
1 var name = 'global'; 2 var obj = { 3 name:'obj', 4 getName:function() { 5 return function () { 6 console.log(this.name); 8 } 10 } 11 } 12 obj.getName() ();
1 function a () { 2 var num = 1; 3 function addNum () { 4 num ++; 5 console.log(num); 6 } 7 return addNum; 8 } 9 var demo = a (); 10 demo(); 11 demo(); 12 var demo1 = a(); 13 demo1(); 14 demo1();
1 (function (){}()) 2 function returnB() { 3 var arr = []; 4 for(i = 0; i < 10; i ++){ 5 arr[i] = (function(){ 6 console.log(i); 7 }()) 8 } 9 return arr; 10 } 11 var save = returnB(); 12 console.log(save); 13 for(j = 0; j < 10; j ++){ 14 save[j]; 15 }
1.对象的建立方式有三点
1 var obj ={};
2.构造函数【constructor】
1 var object = new object();
3.自定义构造函数
1 var function Person () {}; 2 var operson = new Person (); 3 typeof operson // object
1 function Person (name,age) { 2 this.name = name; 3 this.age = age; 4 } 5 var person = new Person('zhangsan',18); 6 console.log(person.name);
1 function Person (name) { 2 var this = {}; 3 this.name = name; 4 return this; 5 }
1 function Person (name) { 2 var that = { 3 name: 'lisi' 4 }; 5 that.name = name; 6 return that; 7 } 8 var person = new Person ('demo'); 9 console.log(person.name)
4.属性的增删改查
1 var obj = {};
2 obj.name = 'xiaoming'
1 var obj = { 2 name:'demo'; 3 } 4 obj.name = 'tan';
1 var obj = { 2 name = 'scerlett' 3 } 4 obj.name; // scerlett 5 delete obj.name; 6 obj.name; // undefined
1.原型的定义:原型是function对象的一个属性,它定义了构造函数制造出来的对象的公有祖先,经过该构造函数产生的对象,能够继承原型的属性和方法,原型也是对象。
1 function Person () {}
2.利用原型特色概念,能够提取公有属性
3.对象如何查看原型
4.如何查看构造自身的构造函数
1 console.log(person.constructor); //person();
1.有了原型,原型仍是一个对象,那么这个名为原型的对象天然还有本身的原型,这样的原型上还有原型的结构就成了原型链。
1 Gra.prototype.firsName = 'scarlett' 2 function Gra () { 3 this.name = 'grandfather'; 4 this.sex = 'male'; 5 } 6 var grandfoo = new Gra(); 7 garndfoo.word = 'hello' 8 Foo.prototype = grandfoo; 9 function Foo () { 10 this.age = '18'; 11 this.money = '100'; 12 } 13 var father = new Foo(); 14 function Son () { 15 this.name = 'son'; 16 } 17 Son.prototype = father; 18 var son = new Son();
2.可是并非全部的对象都有原型,好比使用Object.create方法。
1 var obj = Object.create(Object.prototype);
3.原型链上的增删改查
1 Person.prototype.arr[1,2,3]; 2 var person1 = new Person(); 3 var person2 = new Person(); 4 person1.arr.push(4); 5 console.log(person2);//1 2 3 4
1.this的一些问题:
函数内部的this默认指向window,可使用call / apply来改变this的指向,区别:后面传参形式不一样。
1 function person () { 2 this.name = 'scarlett'; 3 console.log(this); 4 } 5 person();
如今this指向window,name属性天然就是window上的全局属性
var obj = {}; person。call(object)//Object.{name:'scarlett'}
若是这个函数还有参数的话,只要把实参的值写在call后面而且用逗号隔开
function person(name,age){ this.name = name; this.age = age; } var obj = {}; person.call(obj,'scarlett',18); console.log(obj.name);
apply和call基本没什么区别,惟一的区别就是call后面的参数是一个一个传的,而apply后面的参数是放在数组里
person.apply(obj['scarlett',18]);
2.继承【inherit】
圣杯模式
function inherit(Target, Origin) { function F() {}; F.prototype = Origin.prototype; Target.prototype = new F(); Target.prototype.constuctor = Target;//让constuctor指向本身的 Target.prototype.uber = Origin.prototype; //超类,知道本身继承的是谁
yahu封装方法:
1 // var inherit = (function (){ 2 // var F = function () {}; 3 // return function (Target, Origin){ 4 // F.prototype = Origin.prototype; 5 // Target.prototype = new F(); 6 // Target.prototype.constuctor = Target; 7 // Target.prototype.uber = Origin.prototype; 8 // } 9 // }()); 10 // 11 // for (var i = 0; i < 5; i ++) { 12 // var btn = document.createElement('button'); 13 // btn.appendChild(document.createTextNode('Button' + i)); 14 // btn.addEventListener('click', function(){console.log(i); }); 15 // document.body.appendChild(btn); 16 // }
对象的枚举与this
1.对象的枚举
查看对象的属性能够用obj.name查看,也能够用obj['name']类数组方式查看,但事实上是数组模仿了对象的查看方式
2.for-in操做符
要枚举一个数组的全部属性只需用一个for循环从头至尾遍历一遍就能够了。
可是对象并不能用for循环来遍历属性,全部就要用到for-in操做了
1 // var obj = { 2 // name: 'scarlett', 3 // age: 18, 4 // sex: 'female' 5 // } 6 // for(var prop in obj){ 7 // console.log(prop + ':' + obj[prop]); 8 // }
2.三种操做符
hasOwnProperty这个操做符的做用是查看当前这个属性是否是对象自身的属性,在原型链上的属性会被过滤掉,自身的ture
// function Person() { // this.name = 'scarlett' // } // Person.prototype = { // age:18 // } // var oPerson = new Person(); // for (var prop in oPerson) { // if (oPerson.hasOwnProperty(prop)){ // console.log(oPerson[prop]); // } // }
这样for-in循环就只会打印自身的属性,而不是打印原型上的属性
in操做符:这个操做符的做用是查看一个属性是否是在这个对象或者它原型里面。
1 // 'name' in oPerson; //ture 2 // 'sex' in oPerson; //False
instanceof操做符:做用是查看前面对象是否是后面的构造函数构造出来的,和constructor很像
1 // oPerson intanceof object; // ture 2 // {} instanceof oPerson; // false
3.this
1 // var obj = { 2 // height:190, 3 // eat:function () { 4 // this.height ++; // eat在没有执行以前,谁也不知道this指向谁 5 // } 6 // } 7 // obj.eat(); // 谁调用this,this指向谁 8 // eat.call(obj); // eat里面的this指向obj
若是能理解下面的这段代码的this指向问题,那么就掌握的this的全部知识点了
1 // var name = '222' 2 // var a = { 3 // name:'111', 4 // say:function () { 5 // console.log(this.name); 6 // } 7 // } 8 // var fun = a.say; 9 // fun(); // 此处其实就是把a.say这个函数体赋给fun这个函数,至关于在全局空间写下了一个fun函数,此时this指向window,打印'222' 10 // a.say(); // 按照谁调用指向谁的说法,这里打印'111' 11 // var b = { 12 // name:'333', 13 // say:function (fun) { 14 // fun(); 15 // } 16 // } 17 // b.say(a.say); // 其实和在全局调用a.say的函数体方法差很少,打印'222' 18 // b.say = a.say; 19 // b.say(); // this指向B 因此打印'333'
1.argument.callee
这个方法是指代函数自己,当在一些匿名函数或者当即执行函数里面进行递归调用函数自己的时候,因为没有名字,就用这种方式调用;
通常当须要经过计算机进行初始化的时候,写一个当即执行函数,当这个当即执行函数还须要递归调用自身的时候,就用这种方式调用。
2.function.caller
// function test () { // console.log(test.caller); // } // function demo () { // test() // } // demo();
这是函数自己自带的一个属性,能够指出当前函数的ude运行环境的函数引用,就是这个函数在哪一个函数里面执行的……
3.克隆【clone】
克隆和继承有一些区别,克隆是复制出来如出一辙的目标对象又分为浅度克隆和深度克隆
// function clone (src,tar) { // var tar = tar || {}; // for (var prop in src) { // if (src.hasOwnProperty(prop)){ // tar[prop] = src[prop]; // } // } // return tar; // }
当有一个属性是引用值(数组、对象)时按照这种克隆模式,只是把这个引用值的指向赋给了新的目标对象,一旦改变了原对象或者目标对象的引用属性另外一个也跟着变,这一点就是浅度克隆的缺点;
深度克隆的原理很简单,只要不克隆引用值的引用而是把引用值也当作一个原对象,把里面的值一个个克隆岛目标对象里面,就解决了两者相同指向的问题;
// function deepCopy (src,tar) { // var tar = tar || {}; // for (var prop in src) { // if(typeof(src[prop] == 'object')){ // tar[prop] = (src[prop].constructor === Array) ? [] : {}; // }else{ // tar[prop] = src[prop]; // } // } // return tar; // }
这个时候目标对象和原对象的引用值就没有关系了,都是独立值能够进行修改。
4.数组【array】