Javascript中的函数表达式

  • 函数声明 有提升 而函数表达式没有,因此不应该通过if…else来声明函数
     
     
        if (condition) {
            function sayHi() {}
        } else {
            function sayHi() {}
        }
       
  • 在递归函数中使用arguments.callee可以避免因函数名改变产生的错误。
     
     
        function factorial(num) {
            if (num 
                return 1;
            } else {
                return num * arguments.callee(num - 1);
            }
        }
       
  • 闭包是指函数中定义的函数,闭包的作用域链中包含父函数的执行环境(变量对象),所以即使父函数退出,如果闭包仍然被引用,那么父函数的变量对象就一直存在于内存中。所以,过度的使用闭包会导致内存占用过多
  • 闭包的另外一个副作用是闭包只能取得父函数中变量的最后一个值,例如:
     
     
        function createFunctions() {
            var result = new Array();
            for(var i = 0; i < 10; i++) {
                result[i] = function() {
                    return i;
                }
            }
            return result;
        }
       

    调用result中的每个函数都会返回10

  • 闭包如果是匿名函数,则该函数中的this指向全局对象
  • 可以用定义一个立即执行函数来模仿块级作用域:
     
     
            (function(){
            //块级作用域                                   
            })();                                        
       

Javascript中的对象

属性的类型

1.1 数据类属性

数据类属性的属性——特性为:

  • [[Configurable]]: 默认为true。表示能否通过delete删除属性,能否修改属性的特性。
  • [[Enumerable]]: 默认为true。表示在用for-in迭代对象时,能否迭代出该属性。
  • [[Writable]]: 默认为true。表示能否修改属性的值。
  • [[Value]]: 默认为undefined。保存属性的值。

1.2 访问器类属性

访问器类属性的特性为:

  • [[Configurable]]: 默认为true。表示能否通过delete删除属性,能否修改属性的特性。
  • [[Enumerable]]: 默认为true。表示在用for-in迭代对象时,能否迭代出该属性。
  • [[Get]]: 默认为undefined。读取属性时调用的函数。
  • [[Set]]: 默认为undefined。写入属性时调用的函数。

使用访问器类型的属性的常用方法是写入该属性时往往会导致其他属性也跟着变化。

 

1.3 对特性的操作方法:

Object.defineProperty(Object, propertyName, {attributes}): 设置属性的特性。
Object.defineProperties(Object, {propertyName: {attributes},}): 设置多个属性的特性。
Object.getOwnPropertyDescriptor(Object, propertyName);

 

创建对象的方法

2.1 工厂模式

 
 
function createPerson(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var sen = createPerson('sen', 19, 'programer');

缺点:无法识别一个对象属于哪一个类

 
 
alert(sen instanceof createPerson) // false

2.2 构造函数模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function() {
        alert(this.name);
    }
}
var sen = new Person("sen", 19, "programer");
alert(sen instanceof Person) // true
alert(sen.constructor === Person) // true

缺点:每个对象都会有独立的函数定义

 
 
var sen1 = new Person("sen1", 19, "player");
alert(sen1.sayName == sen.sayName) // false

2.3 原型模式

 
 
function Person() {
}
Person.prototype.name = "sen";
Person.prototype.age = "19";
Person.prototype.job = "programer";
Person.prototype.sayName = fucntion() {
    alert(this.name);
}
var sen = new Person();
Person.prototype.constructor === Person // true
Person.prototype.isPrototypeOf(sen) // true
Object.getPrototypeOf(sen) === Person.prototype // true
sen.hasOwnProperty("name") // false
"name" in sen // true

判断属性是不是在原型对象中:

 
 
!sen.hasOwnProperty("name") && ("name" in sen)

原型模式更简洁的写法:

 
 
function Person(){};
Person.prototype = {
    constructor = Person,
    name: "sen",
    age: 19,
    job: "programer",
    sayName: function() {
        alert(this.name);
    }
}
Object.defineProperty(Person.prototype, {
    enumerable: false,
    value: Person
});

缺点:

1. 省略了传递初始化参数
2. 如果原型中的属性为引用类型,则所有对象会共用这个引用类型

2.4 组合使用构造模式和原型模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.sayName = function() {
    alert(this.name)
}

缺点: 构造函数和原型是独立的

2.5 动态原型模式

 
 
function Person(name, age, job) {
    this.name = name;
    this.age = age;
    this.job = job;
    if (typeof this.sayName !== "function") {
        Person.prototype.sayName = function() {
            alert(this.name);
        };
    }
}

2.6 寄生构造函数模式

 
 
function Person(name, age, job) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function() {
        alert(this.name);
    }
    return o;
}
var sen = new Person('sen', 19, 'programer');

寄生构造函数模式一般用于创建特殊的引用类型。例如,创建一个包含toPipedString方法的数组类型。

 
 
function SpecialArray() {
    var arr = new Array();
    arr.push.apply(arr, arguments);
    arr.toPipedString = function() {
        return this.join(" | ");
    }
    return arr;
}
var colors = new SpecialArray("red", "black");
alert(colors.toPipedString());

缺点和工厂模式一样,都无法被instanceof识别

2.7 稳妥构造函数模式

与寄生构造函数类似,区别在于:

  • 不使用this给类添加公共属性
  • 创建对象时不使用new关键字
 
 
  1. function Person(name, age, job) {
  2. var o = new Object();
  3. o.sayName = function() {
  4. alert(name);
  5. }
  6. return o;
  7. }
  8. var sen = Person('sen', 19, 'programer');

缺点和工厂模式一样,都无法被instanceof识别

继承

3.1 原型链

 
 
function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function() {
    return this.property;
}
function SubType() {
    this.subProperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
    return this.subProperty;
}
var obj = new SubType();
alert(obj instanceof SubType) // true
alert(obj instanceof SuperType) // true
alert(obj instanceof Object) // true

缺点:

  • SuperType中的属性如果为引用类型,所以的子类都会共用该属性
  • 创建子类时,如果给父类传递参数,会影响其他的子类

3.2 构造函数继承继承

 
 
function SuperType() {
    this.colors = ['black', 'red'];
}
function SubType() {
    SuperType.call(this);
}

缺点:函数无法复用

3.3 组合继承

 
 
function SuperType(name) {
    this.name = name;
    this.colors = ['black', 'red'];
}
SuperType.prototype.sayName = function() {
    return this.name;
}
function SubType(name) {
    SuperType.call(this, name);
}
SubType.prototype = new SuperType();

3.4 原型式继承

 
 
var person = {
    name: "sen"
}
var newPerson = Object.create(person, {name: {
    value: "yang"
}});

缺点: 原型式继承仅仅是对父类做了一个浅拷贝,并加入了子类自己的属性。所以问题和原型链相同,父类中的引用类型属性会被所有子类共用。

3.5 寄生式继承

 
 
function createAnother(obj) {
    var clone = Object.create(obj);
        clone.sayHi = function() {
        alert('hi');
    }
    return clone;
}

缺点: 函数不能复用

3.6 寄生组合式继承 (常用)

 
 
function inheritPrototype(subType, superType) {
    var prototype = Object.create(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}
function SuperType(name) {
    this.name = name;
    this.colors = ['red', 'black'];
}
SuperType.prototype.sayName = function() {
    alert(this.name);
}
function SubType(name) {
    SuperType.call(this, name);
    this.age = age;
}
inheritPrototype(SubType, SuperType);

Javascript中的单体内置对象

Global

  1. encodeURI() encodeURIComponent(): 用utf-8编码替换URI中的无效字符,区别在于encodeURI并不对属于URI的特殊字符进行编码,如:// #?等
  2. eval(“var msg=’hello world'”); alert(msg);
  3. Global对象的属性:
    • undefined
    • NaN
    • Infinity
    • Object
    • Array
    • Function
    • Boolean
    • String
    • Number
    • Date
    • RegExp
    • Error
    • EvalError
    • RangeError
    • ReferenceError
    • SyntaxError
    • TypeError
    • URIError
  4. 可通过window对象来访问global对象的变量和函数
  5. var global = function(){return this;}();

Math

  • Math对象的属性:
    • Math.E
    • Math.LN10
    • Math.LN2
    • Math.LOG2E
    • Math.LOG10E
    • Math.PI
    • Math.SQRT1_2
    • Math.SQRT2
  • Math.min([1, 2, 3]) Math.max([1, 2, 3])
  • Math.ceil()
  • Math.floor()
  • Math.round()
  • Math.random():  [0-1)
  • Math.abs()
  • Math.exp()
  • Math.log()
  • Math.pow(num, power)
  • Math.sqrt()
  • Math.acos(x)
  • Math.asin(x)
  • Math.atan(x)
  • Math.atan2(y, x)
  • Math.cos(x)
  • Math.sin(x)
  • Math.tan(x)

Javascript中的基本包装类型

当读取一个基本类型(Boolean、String、Number)的值时,后台对创建一个对应的基本包装类型,从而让我们可以调用一些方法来操作这些数据。

基本包装类型与引用类型的区别:

  • 生存期。自动创建的包装类型只存在于一行代码存在的瞬间。不能在运行时为基本类型添加属性和方法。

Number类型常用的方法

  • toString()
  • toFixed(2) //小数点后两位
  • toExponential()
  • toPrecision(3)

String类型常用的属性和方法

  • length: 返回字符串的长度
  • charAt(2) charCodeAt(2): 返回字符串中第三个字符/编码
  • concat(“xxx”) 或者 + “xxx”: 字符串拼接
  • slice(start, end) subString(start, end) subStr(start, number): 字符串切片
    当start为负值时,slice和subStr会把它与字符串长度相加得到新的start;而subString则会将其转化为0
    当end/number为负值时,slice会把它与字符串长度相加得到新的end,subStr和subString会将其转化为0
  • indexOf(‘d’, start) 和lastIndexOf(‘d’, start): 从start位置开始向左(右)查找’d’在字符串中的位置
  • trim(): 返回删除字符串左右的空格的新字符串
  • trimLeft() trimRight(): 返回删除字符串左(右)的空格的新字符串
  • toLowerCase() toLocaleLowerCase() toUpperCase() toLocaleUpperCase()
  • match(pattern/RegExp): 返回的数组与RegExp.exec相同
  • search(pattern/RegExp): 返回匹配到的位置
  • replace(old, new):
    如果old为字符串时,仅替换该字符串;如果Old是带’g’标志的pattern时,会替换所有匹配的字符串
    new字符串中可以是下列特殊序列:
    $$: $
    $&: 等价于RegExp.lastMatch
    $’: RegExp.leftContext
    $`: RegExp.rightContext
    $n $nn: 第n个捕获组匹配到的字符串
    new可以是一个函数:function(match, pos, orignialText){return string}
  • var array = “string”.split(‘string/pattern’, number)

Javascript中的函数

函数的定义

  1.  var foo = fucntion(a, b) {}; //函数表达式
  2. function foo(a, b) {}; //函数声明
  3. var foo = new Function(“a”, “b”, “return false”); //不推荐

对于函数声明,可以在声明之前调用该函数;而对于函数表达式,不可以在表达式之前调用该函数。

函数的属性

  • this: 引用的是函数执行的环境对象,全局作用域中的this引用的是window对象
  • arguments: 保存函数参数的数组
  • arguments.callee: 指向该函数的指针
  • caller: 函数的调用者
  • length: 函数希望接收到的命名参数的个数

函数的方法

  • call(obj, arg1, arg2…)  //设置函数的运行环境(改变this的值)
  • apply(obj, [arg1, arg2]) //设置函数的运行环境(改变this的值)
  • bind(obj) //绑定函数的运行环境

Javascript中的正则表达式

1. RegExp类型的创建

var expression = /pattern/flags; 或者

var expression = new RegExp(“pattern”, “flags”);

用创建对象的方式来创建RegExp是需要对”pattern”中的\进行转义,例如:

/\[bc\]at/  => “\\[bc\\]at”

flags 可以是:

  • g :全局匹配
  • i :忽略大小写
  • m :多行模式

2. RegExp实例的属性

  • global: true or false, 表示标志位’g’是否被设置
  • ignoreCase: true or false
  • multiline: true or false
  • lastIndex: 下一次搜索开始的字符位置
  • source: pattern的字符串表示

3. RegExp实例的方法

  • exec(“target_string”)
    • ret.index: 匹配到的字符串的起始位置
    • ret.input: “target_string”
    • ret[0]: 匹配到的字符串
    • ret[1 – n]: 匹配组1-n匹配到的字符串
  • test(“target_string”)
    • true: 匹配到字符串
    • false: 没有匹配到字符串
  • exec和test只有在设置了’g’标志位的情况下才回去更新exp.lastIndex

4. RegExp 构造函数属性

  • input ($_): 最近一次匹配成功的源字符串
  • lastMatch($&): 最近一次的匹配项
  • lastParen($+): 最近一次匹配的捕获组
  • leftContext($`): input字符串中匹配项之前的字符串
  • rightContext($*): input字符串中匹配项之后的字符串
  • $1-9: 第1-9个匹配组

附录:

正则表达式元字符表

Metacharacter Description
^ Matches the starting position within the string. In line-based tools, it matches the starting position of any line.
. Matches any single character (many applications exclude newlines, and exactly which characters are considered newlines is flavor-, character-encoding-, and platform-specific, but it is safe to assume that the line feed character is included). Within POSIX bracket expressions, the dot character matches a literal dot. For example, a.c matches “abc”, etc., but [a.c] matches only “a”, “.”, or “c”.
[ ] A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches “a”, “b”, or “c”. [a-z] specifies a range which matches any lowercase letter from “a” to “z”. These forms can be mixed: [abcx-z] matches “a”, “b”, “c”, “x”, “y”, or “z”, as does [a-cx-z].The - character is treated as a literal character if it is the last or the first (after the ^, if present) character within the brackets: [abc-], [-abc]. Note that backslash escapes are not allowed. The ] character can be included in a bracket expression if it is the first (after the ^) character: []abc].
[^ ] Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than “a”, “b”, or “c”. [^a-z] matches any single character that is not a lowercase letter from “a” to “z”. Likewise, literal characters and ranges can be mixed.
$ Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.
( ) Defines a marked subexpression. The string matched within the parentheses can be recalled later (see the next entry, \n). A marked subexpression is also called a block or capturing group. BRE mode requires \( \).
\n Matches what the nth marked subexpression matched, where n is a digit from 1 to 9. This construct is vaguely defined in the POSIX.2 standard. Some tools allow referencing more than nine capturing groups.
* Matches the preceding element zero or more times. For example, ab*c matches “ac”, “abc”, “abbbc”, etc. [xyz]* matches “”, “x”, “y”, “z”, “zx”, “zyx”, “xyzzy”, and so on. (ab)* matches “”, “ab”, “abab”, “ababab”, and so on.
{m,n} Matches the preceding element at least m and not more than n times. For example, a{3,5} matches only “aaa”, “aaaa”, and “aaaaa”. This is not found in a few older instances of regexes. BRE mode requires \{m,n\}.

 

Metacharacter Description
? Matches the preceding element zero or one time. For example, ab?c matches only “ac” or “abc”.
+ Matches the preceding element one or more times. For example, ab+c matches “abc”, “abbc”, “abbbc”, and so on, but not “ac”.
| The choice (also known as alternation or set union) operator matches either the expression before or the expression after the operator. For example, abc|def matches “abc” or “def”.

 

POSIX Non-standard Perl/Tcl Vim Java ASCII Description
[:ascii:][30] \p{ASCII} [\x00-\x7F] ASCII characters
[:alnum:] \p{Alnum} [A-Za-z0-9] Alphanumeric characters
[:word:][citation needed] \w \w \w [A-Za-z0-9_] Alphanumeric characters plus “_”
\W \W \W [^A-Za-z0-9_] Non-word characters
[:alpha:] \a \p{Alpha} [A-Za-z] Alphabetic characters
[:blank:] \s \p{Blank} [ [[\t]]] Space and tab
\b \< \> \b (?<=\W)(?=\w)|(?<=\w)(?=\W) Word boundaries
\B (?<=\W)(?=\W)|(?<=\w)(?=\w) Non-word boundaries
[:cntrl:] \p{Cntrl} [\x00-\x1F\x7F] Control characters
[:digit:] \d \d \p{Digit} or \d [0-9] Digits
\D \D \D [^0-9] Non-digits
[:graph:] \p{Graph} [\x21-\x7E] Visible characters
[:lower:] \l \p{Lower} [a-z] Lowercase letters
[:print:] \p \p{Print} [\x20-\x7E] Visible characters and the space character
[:punct:] \p{Punct} [][!"#$%&'()*+,./:;<=>?@\^_`{|}~-] Punctuation characters
[:space:] \s \_s \p{Space} or \s [ \t\r\n\v\f] Whitespace characters
\S \S \S [^ \t\r\n\v\f] Non-whitespace characters
[:upper:] \u \p{Upper} [A-Z] Uppercase letters
[:xdigit:] \x \p{XDigit} [A-Fa-f0-9] Hexadecimal digits

 

常用分组语法
分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

 

常用的反义代码
代码/语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

 

 

 

Javascript中的Date

1. Date类型的创建

  • var date = new Date() //获取当前时间
  • var date = new Date(ms) //根据Unix时间戳来创建Date对象
  • var date = new Date(Date.parse(“string”)) //string为日期时间组成的字符串,符合要求的字符串格式包括:
    • “m/d/y”
    • “January 12, 2004”
    • “Tue May 25 2004 00:00:00 GMT-0700”
    • YYYY-MM-DDTHH:mm:ss.sssZ”
  • var date = new Date(Date.UTC()) // Date.UTC的参数为年、月、日、小时、分钟、秒、毫秒

2. Date类型的操作

var date = new Date();

  • Date.now() 或者+new Date()获取当前的时间戳, “+”操作符可获取Date对象的时间戳
  • date.toDateString(); // “Thu May 17 2018”
  • date.toTimeString(); // “14:37:29 GMT+0800 (CST)”
  • date.toLocaleDateString(); // “2018/5/17”
  • date.toLocaleTimeString(); // “下午2:37:29”
  • date.toUTCString(); // “Thu, 17 May 2018 06:37:29 GMT”
  • date.toLocaleString(); // “2018/5/17 下午2:37:29”
  • date.getTime(); // 1526539049298
  • +date; // 1526539049298
  • date.setTime(1526539049300);
  • date.getFullYear(); // 2018
  • date.getUTCFullYear(); // 2018
  • date.getMonth(); // 0-11
  • date.getUTCMonth(); // 0-11
  • date.getDate(); //1-31
  • date.getUTCDate(); // 1-31
  • date.getDay(); // 0-6 0表示周日
  • date.getUTCDay(); // 0-6 0表示周日
  • date.getHours(); // 0-23
  • date.getUTCHours(); // 0-23
  • date.getMinutes(); // 0-59
  • date.getUTCMinutes(); // 0-59
  • date.getSeconds(); // 0-59
  • date.getUTCSeconds(); // 0-59
  • date.getMilliseconds(); // 0-999
  • date.getUTCMilliseconds(); // 0-999
  • date.getTimezoneOffset(); // -480

Javascript中的数组

  • 数组的定义:
    • var colors = new Array(20);
    • var colors = new Array(‘red’);  // [‘red’]
    • var colors = [‘red’, ‘green’];
  • 判断变量是不是数组:
    • colors instanceof Array;  //true
    • Array.isArray(colors); //true
  • 将数组转化为字符串:
    • colors.toString(); // ‘red,green’
    • colors.join(‘ ‘); //’red green’
    • colors = [ “red”, undefined, “green”, null, “yellow” ];
      • colors.toString(); //"red,,green,,yellow"
        
        colors.join(' '); //"red  green  yellow"
        
        colors.join(';'); //"red;;green;;yellow"
  • 栈方法
    • colors.push(‘yellow’); //[‘red’, ‘green’, ‘yellow’]
    • colors.pop(); //[‘red’, ‘green’]
  • 队列方法
    • colors.push(‘yellow’); //[‘red’, ‘green’, ‘yellow’]
    • colors.shift(); //[‘green’, ‘yellow’]
    • colors.unshift(‘black’); //[‘black’, ‘red’, ‘green’]
  • 重新排序
    • colors.reverse(); //[‘green’, ‘red’]
    • colors.sort();
      • 字符串升序排列
        • var nums = [1, 5, 10]; //nums.sort();//[1, 10, 5]
      • colors.sort(function(a,b){return a – b;});升序排列
      • colors.sort(function(a,b){return b – a;});降序排列
  • 操作
    • var ret = colors.concat(‘black’); // ret = [‘red’, ‘green’, ‘black’]
    • var ret = colors.slice(0, 1); //[‘red’] 切片
    • colors.splice(pos, length, item, item…); 在pos处删除length项,然后插入item…
  • 位置
    • indexOf(‘red’); //0
    • lastIndexOf(‘red’); //0
  • 迭代
    • colors.every(function(item, index, array){}); 所有元素返回true则返回true
    • colors.filter(function(item, index, array){}); 返回为true的元素组成的数组
    • colors.forEach(function(item, index, array){}); 无返回值
    • colors.map(function(item, index, array){}); 返回函数调用结果组成的数组
    • colors.some(function(item, index, array){}); 如果有一项返回true则返回true
  • 归并方法
    • var sum = values.reduce(function(prev, cur, index, array){return prev + cur}, 0);
    • reduceRight(); 从后往前循环

Javascript中的基本数据类型

Undefined

  • 在var或者let中声明了变量但没有赋值时,这个变量的值就是undefined.
  • 使用typeof关键字检测未声明变量的类型为undefined.

Null

  • null表示一个空对象指针,所以用typeof检测null时,会返回object
  • undefine派生自null, null == undefined 为true, null === undefined为false

Boolean

  • true false 区分大小写
  • 空字符串、0和NaN、null、undefined转换为boolean的值为false

Number

  • Number表示整数和浮点数
  • 八进制数以0开头,十六进制数以0x开头
  • Number.MIN_VALUE 表示Javascript支持的正的最小数值,Number.MAX_VALUE表示Javascript支持的最大数值
  • 超出最大数值就会被转化为Infinity,如果为负值则会被转化为-Infinity
  • isFinite()函数可以判断一个数值是否在支持的范围之内
  • NaN表示本来该返回数值的操作数未返回数值的情况,如除以0就会返回NaN
  • NaN的数值运算会返回NaN
  • NaN == NaN 为false
  • isNaN()函数可以判断一个数值是不是NaN
  • Number()函数可以将其他类型的值转换为Number类型:
    • Number(true) = 1; Number(false) = 0;
    • Number(null) = 0;
    • Number(“”) = 0; Number(“0x1a”) = 26; Number(‘076’) = 76;
    • Number(‘100hello’) = NaN;
    • 如果是对象,则会调用对象的valueOf()方法,如果返回的是NaN则会先调用toString方法转化为字符串,然后根据字符串的转换规则来转换
  • parseInt()函数:
    • parseInt(‘100hello’) = 100;
    • parseInt(”) = NaN;
    • parseInt(‘0x1a’) = 26;
    • parseInt(‘076’) = 76; parseInt(‘076’, 8) = 62;
  • parseFloat()与parseInt()类似,但有如下区别:
    • parseFloat不能传入第二个参数(进制),不能解析十六进制字符串

String

  • 字符串一旦创建,其值不能改变,如:var lang = ‘Java’; lang += ‘Script’; 会重新创建一个字符串,填充上’JavaScript’, ‘Java’和’Script’都将被销毁
  • 除了null和undefined之外,其他的几个数据类型都有toString()方法,可以将其转换为字符串
  • 数值类型调用toString()方法可以传入进制作为参数,如:var a=20; a.toString(2);
  • String()方法可以将null转化为’null’,把undefined转化为’undefined’

React 概要

React 简介

React 是一个开源的javascript库,用来构建用户接口(UI)。下图是React的一些基本信息:

React 的特点

  1. 单向数据流
    • 数据自上而下
      • Props 不可变
      • States可变
      • 任何数据、函数都可以作为属性(props)传    递给子组件(Props, States, Handlers, Styles)
    • 事件冒泡
      • 子组件触发的事件会传递到父组件
  2. 虚拟DOM
    • Javascript内存中的DOM数据缓存
    • 组件发生变化时渲染虚拟DOM
    • React将虚拟DOM与DOM的差异转化为一系列的DOM操作
    • 将这些操作同步应用到真实的DOM中
  3. JSX
    • 可以使用HTML语法创建Javascript 对象
    • 代码更少
    • 会被转化为Javascript执行
      • Offline – react-tools
      • In-Browser – JSXTransformer
    • 不改变Javascript语义
  4. 其他特点
    • 元素嵌套: 每个组件只允许有一个顶层元素(div, table …)
    • 自定义属性: 除了HTML标签自带属性之外,React也支持自定义属性,自定义属性需要加上data- 前缀
    • JavaScript表达式: 可以通过{}在JSX中使用Javascript表达式
    • 三目运算符: JSX中不能使用if-else但可以使用三目运算符

React元素

const element = <h1>Hello, world</h1>;

  • React 元素 != DOM 元素
  • 将元素渲染到 DOM 中

    ReactDOM.render(element, document.getElementById(‘root’));
     

  • 更新元素 – 重新 Render
  • 更新元素只会更新变化的部分
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}
setInterval(tick, 1000);

React组件

组件可以将UI切分成一些的独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。

  • 如何定义一个组件
    • 函数
      function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
      }

       

    • class
      class Welcome extends React.Component {
        render() {
          return <h1>Hello, {this.props.name}</h1>;
        }
      }

       

  • 渲染组件
    • const element = <Welcome name=”Sara” />;
  • 组合组件
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

状态与生命周期

因为react中props为只读,如果需要更新数据,可以使用react中的状态。在使用状态之前,需要把组件函数转变为类。

  • 创建一个名称扩展为 React.Component 的ES6 类
  • 创建一个叫做render()的空方法
  • 将函数体移动到 render() 方法中
  • 在 render() 方法中,使用 this.props 替换 props
  • 删除剩余的空函数声明

将组件函数转化为类之后就可以添加状态了:

  • 在 render() 方法中使用 this.state.date 替代 this.props.date
  • 添加一个类构造函数来初始化状态 this.state
  • 使用 this.setState() 来更新组件局部状
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  tick() {
    this.setState({
      date: new Date()
    });
  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

事件处理

  • React事件绑定属性的命名采用驼峰式写法,而不是小写。
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)
  • React不能使用返回 false 的方式阻止默认行为

条件渲染

  • 使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI
  • 使用变量来储存元素
    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }
      return <GuestGreeting />;
    }
    ReactDOM.render(
      // Try changing to isLoggedIn={true}:
      <Greeting isLoggedIn={false} />,
      document.getElementById('root')
    );

     

  • &&运算符
    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      return (
        <div>
          <h1>Hello!</h1>
          {unreadMessages.length > 0 &&
            <h2>
              You have {unreadMessages.length} unread messages.
            </h2>
          }
        </div>
      );
    }

     

  • 三目运算符
    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
        </div>
      );
    }

     

列表渲染

  • React 可以直接渲染列表
  • Keys可以在DOM中的某些元素被增加或删除的时候帮助React识别哪些元素发生了变化。因此应当给数组中的每一个元素赋予一个确定的标识。
  • 元素的key只有在它和它的兄弟节点对比时才有意义
  • jsx中可以使用map
function ListItem(props) {
  return <li>{props.value}</li>;
}
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

表单

  • HTML表单元素与React中的其他DOM元素有所不同,因为表单元素生来就保留一些内部状态
  • 在HTML当中,像<input>,<textarea>, 和 <select>这类表单元素会维持自身状态,并根据用户输入进行更新
  • 在React中,可变的状态通常保存在组件的状态属性中,并且只能用 setState(). 方法进行更新
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }
  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }
  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

 

"