JS基础
- 数据类型
String
(1)单双引号都可
(2)ECMAScript中字符串不可改变var lang = "java";
lang = lang + "Script";
- 解决办法(模拟Java中的StringBuffer):
function StringBuffer(){
this._strings_ = new Array();
}
StringBuffer.prototype.append = function(str){
this._strings_.push(str);
return this;
}
StringBuffer.prototype.toString = function(){
return this._strings_.join("");
}
(3)String对象的常用方法
charCodeAt(index):返回一个整数,代表指定位置字符的Unicode编码var str = "ABC";
str.charCodeAt(0); //65
var str = "ABC";
str.charAt(1); // B
- 如果参数为负值则做length+start处理。
var str = "ABCDEF";
str.slice(2,4); // CD
var str = "ABCDEF";
str.substring(2,4); // CD 同str.substring(4,2)
var str = "ABCDEF";
str.substr(2,4); // CDEF
var str = "ABCDEF";
str.substr("CD"); // 3
Js对boolean的判断'' == '0' // false
2. 0 == '' // true
3. 0 == '0' // true
4. false == 'false' // false
5. false == '0' // true
6. false == undefined // false
7. false == null // false
8. null == undefined // true
9. true == 1 // true
10. '' == null // false
11. false == '' // true
- 数据类型 转换为true的值 转换为false的值
- 数据类型
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空的字符串 | “”(空字符串) |
Number | 任何非0数值(包括无穷大) | 0和NAN |
Object | 任何对象 | null |
Undefined | 不适用 | undefined |
“==”与“===”判断的不同
先说 ===,这个比较简单。下面的规则用来判断两个值是否===相等:
1、如果类型不同,就[不相等]
2、如果两个都是数值,并且是同一个值,那么[相等];(!例外)的是,如果其中至少一个是NaN,那么[不相等]。
(判断一个值是否是NaN,只能用isNaN()来判断)
3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。
4、如果两个值都是true,或者都是false,那么[相等]。
5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。
6、如果两个值都是null,或者都是undefined,那么[相等]。
再说 ==,根据以下规则:
1、如果两个值类型相同,进行 === 比较。
2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较:
a、如果一个是null、一个是undefined,那么[相等]。
b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。
d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。
对象转换成基础类型,利用它的toString或者valueOf方法。 js核心内置类,会尝试valueOf先于toString;
例外的是Date,Date利用的是toString转换。
e、任何其他组合,都[不相等]。
举例:
"1" == true
类型不等,true会先转换成数值 1,现在变成 "1" == 1,再把"1"转换成 1,比较 1 == 1, 相等。
= 赋值运算符
== 等于
=== 严格等于
例:
var a = 3;
var b = "3";
a==b 返回 true
a===b 返回 false
因为a,b的类型不一样
===用来进行严格的比较判断
Number
(1)整数及浮点数(浮点数值必须包含一个小数点,且小数点后面至少有一位数字)
(2)浮点数计算会产生舍入误差,如:
var a = 0.1;
var b = 0.2;
console.log(a+b); //0.30000000000000004
或
alert(0.7+0.1); //0.7999999999999999
alert(0.6+0.2); //0.8
解决办法
先乘再除(较为常用)
其他解决办法:
http://www.cnblogs.com/xinggood/p/6639022.html
(3)NaN表示非数字类型
NaN与任何值(包括自身)相比结果均为false,判断某一值是否为NaN不能用==及===,要使用isNaN(),返回true或false
Undefined
表示变量初始化但为定义
Null
空对象的引用,typeOf(null)结果为”object”
变量提升
var a = 100;
myfun();
function myfun(){
console.log(a); //undefined
var a = 50;
console.log(a); //50
}
Js分为预加载阶段及执行期两个阶段,前者只会确定变量的作用域,在执行期才会为变量赋值。
闭包
(1)作用域变量
变量作用域分为两种:全局变量、局部变量
函数内部可以读取全局变量,而函数外部不可以读取函数内部的变量,注意声明一个局部变量的时候必须带上var,否则声明的是全局变量。
链式作用域:子对象会向上一级一级的寻找所有父对象的变量。所有函数都是全局变量window的子函数。
(2)闭包概念
使用被作用域封闭的变量,函数,闭包等执行的一个函数的作用域
function f1(){
var n=999;
function f2(){
var m = 10;
console.log(m);
}
return f2;
}
var result=f1();
result(); // 10
经常遇到的坑:
for(var i=0;i<mydiv.length;i++){
mydiv[i].onclick = function(){
alert(i);
};
}
输出是?
解决办法:利用闭包使变量暴露出来
for(var i=0;i<mydiv.length;i++){
(function(){
var index = i;
mydiv[index].onclick = function(){
alert(index);
};
})()
}
This
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象
情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window
function a(){
var user = "追梦子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。
var o = {
user:"追梦子",
fn:function(){
console.log(this.user); //追梦子
}
}
o.fn();
情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。
var o = {
a:10,
b:{
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
易混淆:
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //undefined
console.log(this); //window
}
}
}
var j = o.b.fn;
j();
改变this的指向(apply、call、bind):
var name = "window";
var person = {
name: "kxy"
};
function sayName() {
console.log(this.name);
}
sayName(); //window
sayName.apply(person); //kxy
jQuery基础知识
1、 window.onload 与ready方法对比
window.onload的方法是页面所有资源都加载完成在执行。
ready()方法在页面Dom加载结束后,整个页面加载结束前执行代码,节约时间。
2、 jq选择器
层次选择器:
选择器 | 描 述 | 返 回 | |
$(“ancestor descendant") | 匹配ancestor里的所有 descendant(后代)元素 | 集合元素 | |
$(“parent>child") | 匹配parent下的所有 child(子)元素 | 集合元素 | |
$(“prev+next") | 匹配紧接在prev后的 next元素 | 集合元素 | |
$(“prev~siblings") | 匹配prev后的所有 siblings元素 | 集合元素 |
过滤选择器:
选择器 | 描 述 |
:first | 选取第1个元素 |
:last | 选取最后一个元素 |
:not(selector) | 去除所有与给定选择器匹配的元素 |
:even | 选取索引是偶数的所有元素,索引从0开始 |
:odd | 选取索引是奇数的所有元素,索引从1开始 |
:eq(index) | 选取索引等于index的元素,index从0开始 |
可见性过滤选择器:
选择器 | 描 述 | 返 回 | |
:hidden | 匹配所有不可见 的元素 | 集合元素 | |
:visible | 匹配所有可见元素 | 集合元素 |
子元素过滤选择器:
选择器 | 描 述 | 返 回 | |
:nth-child | 匹配每个父元素下的 第index个子元素 索引从1开始 | 集合元素 | |
:first-child | 匹配每个父元素的 第一个子元素 | 集合元素 | |
:last-child | 匹配每个父元素的 最后一个子元素 | 集合元素 | |
: only-child | 某元素是它父元素中 的唯一的子元素 则匹配它 | 集合元素 | |
3、 对DOM的操作
插入节点:
append(): 向每个匹配的元素内部追加内容.
appendTo(): 将所有匹配的元素追加到指定的元素中,即$(A).appendTo(B),是将A追加到B中.
prepend(): 向每个匹配的元素内部前置内容.
prependTo(): 将所有匹配的元素前置到指定的元素中,即$(A).prependTo(B),是将A前置到B中.
前面几个方法都是插入子元素,后面的这几个方法是插入兄弟元素.
after(): 在每个匹配的元素之后插入内容.
insertAfter(): 将所有匹配的元素插入到指定元素的后面.
before(): 在每个匹配的元素之前插入内容.
insertBefore(): 将所有匹配的元素插入到指定元素的前面.
移动节点:
<ul>
<li title="li1">1</li>
<li title="li2">2</li>
<li title="li3">3</li>
<li title="li4">4</li>
<li title="li5">5</li>
</ul>
js:
$(document).ready(function(){
$("ul li:eq(0)").appendTo("ul");
});
- 2
- 3
- 4
- 5
- 1
删除节点:
remove(): 默认情况下会删除选择器选中的所有元素.会返回被删除节点的jQuery对象.可以把这个对象插入到其他的地方.
var removeLi = $("ul li:eq(0)").remove();//delete
removeLi.appendTo($("ul"));//add removed li
empty(): 删除匹配的元素集合中所有内容,包括子节点.注意,元素本身没有被删除.
$(“ul li:eq(3)”).empty();
- 1
- 2
- 3
- 5
复制节点:
clone(): 创建匹配元素集合的副本.
clone(true): 复制节点,包括所有的事件处理.
clone(false): 复制节点,但不包括事件处理.不带参数时默认是这种情况.
替换节点:
replaceAll(): 用指定的HTML内容或元素替换被选元素.
语法: $(content).replaceAll(selector).
replaceWith(): 用新内容替换所匹配到的元素.
语法: $(selector).replaceWith(content).
其中的content可以是HTML代码,可以是新元素,也可以是已经存在的元素。用已有元素替换,原来的元素是会被移除的。
CSS
结合项目
1、 模块化
var module = (function(){
//操作中途停靠
var OperatorStops = function(){
//中途停靠dialog格式定义
$("#tblAdditionalStop").dialog({
title: "中途停靠",
draggable: false,
resizable: false,
modal: true,
width: 600,
height: 700,
autoOpen: false,
closeOnEscape: false
});
}
var ChangePuAddressType = function(obj){
var i = $(":radio[name='rdPuAddressType']").index(obj);
if (i == 0) {
$("#tblPuLocater").css("display", "none");
} else {
$("#tblPuLocater").css("display", "");
}
$(".tblPuPanel").css("display", "none");
$(".tblPuPanel").eq(i).css("display", "");
}
return {
OperatorStops:OperatorStops,
ChangePuAddressType:ChangePuAddressType
}
})();
module.OperatorStops();
2、多封装,如:各种验证
var validate = (function(){
//验证手机号
var testPhone = function(val){
if(!(/^1[34578]\d{9}$/.test(val))){
return false;
}else{
return true;
}
}
var testMail = function(val){
if(!(/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(mail))){
return false;
}else{
return true;
}
}
return {
testPhone : testPhone,
testMail : testMail
}
})();
$("#btnConfirmOrderInformation").click(function () {
if(validate.testPhone($("#txtBookerPhone").val())==false){
alert('手机号错误');
return false;
}else{
$("#txtBookerPhone").css("background-color", "white");
}
});
3 、何时验证
4、js 写法优化
利用好选择器,可将代码简化
原代码:
/选项卡菜单设计和使用
function tabChange() {
$(".tab_content").css("display", "none");
$(".tab_content:eq(0)").css("display", "");
$(".tab_index").click(function () {
$(".tab_background span[class!='tab_index_close']").removeClass();
$(".tab_background span[class!='tab_index_close']").addClass("tab_index");
$(this).addClass("tab_index_active");
$(".tab_content").css("display", "none");
$(".tab_content").eq($(this).index()).css("display", "");
if ($(".tab_index").index(this) == $(".tab_index").length - 1) {
$("#btnNext").css("display", "none");
} else {
$("#btnNext").css("display", "");
}
$("#tab_current_index").val($(".tab_index").index(this));
//在切换到价格Tab时自动执行获取报价操作
if ($(this).index() == "2") {
//只有创建订单,或者修改订单同时价格控件值为空时才需要获取报价
if ($("#hdnActionType").val() == "" || ($("#hdnActionType").val() != "" && $("#txtPrice").val() == "")) {
//获取自动报价
ajaxGetChauffeurPrice();
}
}
});
$(".tab_index:eq(0)").addClass("tab_index_active");
if ($("#tab_current_index").val() != "") {
$(".tab_index").eq($("#tab_current_index").val()).click();
}
}
改进后代码:
$(".tab_index").click(function(){
$(this).siblings().removeClass('tab_index_active');
$(this).addClass('tab_index_active');
$(".tab_content").css('display','none');
$(".tab_content:eq("+$(this).index()+")").css('display','block');
//下一步按钮
if ($(".tab_index").index(this) == $(".tab_index").length - 1) {
$("#btnNext").css("display", "none");
} else {
$("#btnNext").css("display", "");
}
//在切换到价格Tab时自动执行获取报价操作
if ($(this).index() == "2") {
//只有创建订单,或者修改订单同时价格控件值为空时才需要获取报价
if ($("#hdnActionType").val() == "" || ($("#hdnActionType").val() != "" && $("#txtPrice").val() == "")) {
//获取自动报价
ajaxGetChauffeurPrice();
}
}
});