第一篇就献给自己学习javascript的一份笔记吧

javascript作为一种脚本语言可以放在html页面中任何位置,但是浏览器解释html时是按先后顺序的,所以前面的script就先被执行。比如进行页面显示初始化的js必须放在head里面,因为初始化都要求提前进行(如给页面body设置css等);而如果是通过事件调用执行的function那么对位置没什么要求的。
单行注释,在注释内容前加符号 “//”
多行注释以"/*"开始,以"*/"结束

js数据类型
弱类型特性
原始类型 number string boolean null undefined
object 对象 Funtion Array Date

隐身转换
=== 类型不同 false
类型相同 NAN和任何东西比都不相等
对象的比较是通过引用比较 两个对象比较是不相等的
尝试类型转换和比较
null==undefined
number==string 转number
boolean==? 转number 1==true
object==number|string尝试对象转为基本类型 new string("hi")=="hi";
其他false

包装对象
string object string
number object number
boolen object boolen
使用原始类型进行操作 如调用方法、添加属性时会使用其包装类型 等同于新建一个object 但是完成后就会将这个
包装类型移除 不能得到添加的属性

类型检测
typeof 返回字符串 适合函数对象和基本类型判断
typeof function “function” typeof NaN “number”
注意typeof number “object” typeof null “object”(历史原因导致不能判断null)
instanceof 基于原型链 适合对象
左操作的对象的原型链上是否有右边构造函数的prototype属性

obj instanceof Object
左操作数基本类型则直接false
希望右操作数是函数对象或函数构造器 不是抛出error
任何一个构造函数都有一个prototype的对象属性 将用做通过new构造函数方式构造的对象原型
不同window或iframe之间对象检测不能使用instanceof 对象比较是通过引用 不同window下自然不同

Object.prototype.toString.apply([])==="[object Array]"
适合内置对象和基本类型 数值 函数
IE678 null和undefined返回[object object]

constructor 没个对象都有 继承自原型 指向构造这个对象的构造函数

duck type 通过特征 如数组有slice length

 


表达式是指能计算出值得任何可用程序单元
原始表达式
常量 直接量
关键字
变量

数组、对象的初始化表达式
{x:1,y:2} var o=new Object(); o.x=1 o.y=2;
函数表达式
属性访问表达式
o.x o[‘x‘]
调用表达式
对象创建表达式 new Object;

运算符
操作数数量
赋值 比较 算数 位 逻辑 字符串 特殊

var val=(1,2,3); 每个表达式都被计算 val=3
Object.defineProperty(obj,‘x‘,{
configurable:false,
value:1
})
无法 delete obj.x

in运算符
function Foo(){}
Foo.prototype.x=1;
new var obj=new Foo();
obj.hasOwnProperty(‘x‘);
obj._proto_.hasOwnProperty(‘x‘);

this运算符

void 0 undefined

对象
属性时无序的
一个字符串key对应value
属性标签writable enumerable configurable value 方法get/set
[[proto]] [[class]] [[extensible]]

创建对象
字面量(嵌套)

new/原型链
function foo(){}
foo.prototype.z=3 [[proto]] Object.prototype 再往上原型null
var obj=new foo(); [[proto]] foo.prototype
type of obj.toString; "function"
‘z‘ in obj; true
obj.hasOwnProperty(‘z‘); false
给对象赋值不会向原型链查找即不改变原型链上的值
delete不会影响到原型链

var obj=Object.create({x:1});
obj.hasOwnProperty(‘x‘); false
var obj=Object.create(null);
obj.toString; undefined

属性读写
obj.x 常用
obj["x"]
for(;i<=n;i++){
console.log(obj[‘x‘+i]);
}
var p:
for(p in obj){ //原型链上的属性、顺序不确定
console.log(obj[p]);
}

delete Object.prototype; false
var descriptor=Object.getOwnPropertyDescriptor(Object,‘prototype‘);
descriptor.configurable; false

var定义的全局变量 局部变量是不能删除的
函数声明也是 全局 内部
都是不能delete
如果是隐式创建 ohNo=1;window.onNo;// 1 delete ohNo; //true
eval() 可以被delete

属性检测
in操作符 原型链
hasOwnProperty
propertyIs 是否可枚举 toString不可枚举 原型链上大部分是不可枚举

Object.defineProperty(对象,属性名,对象(设置标签{enumerable:false,vale:1000});) 默认writable/configurable等都是false
其他方式创建的对象 默认可枚举、configurable都是true

car.legs!=undefined 等价于 !==undefined !==null 非严格等于下 undefined==null

for(key in obj){
if(obj.hasOwnProperty(key)){
console.log(key);
}
}

另一种读写属性方法
getter/setter
get age(){ return ..},
set age(val){..} 还是用逗号隔开
function foo(){
Object.defineProperty(foo.prototype,‘z‘,{get:function(){return 1;}});
}
var obj = new foo();
obj.z; //1
obj.z=100;
obj.z; //1
由于z在赋值创建时在obj中是没有的 而原型链中有set get方法时 回调用原型链的get方法 而不是像正常情况下写入obj中
只能采用
Object.defineProperty(obj,‘z‘,{value:100,configurable:true});
delete obj.z; //true
obj.z; //1

属性级的权限设置
Object.getOwnPropertyDescriptor({pro:true},‘pro‘); 判定的对象 字符串属性名
writable 属性是否可修改 写 enumerable 是否可被遍历 for in configurable是否可被修改 delete

var person={};
Object.defineProperty(person,‘name‘,{
configurable:fales;
writable:false;
enumerable:true;
value:"Bosn Ma"
});
Object.defineProperty(person,‘type‘,{
configurable:true;
writable:true;
enumerable:false;
value:"Object"
});
Object.keys(person); //["name"]
Object.defineProperties(person,{
title:{value:‘fe‘,enumerable:true}, //没写的属性默认false
corp:{value:‘BABA‘,enumerable:true}},
salary:{value:50000,writable:true,enumerable:true},
luck:{
get:function(){
return Math.random()>0.5?‘good‘:‘bad‘;
}
},
promote;{
set:function(level){
this.salary*=1 + level*0.1;
}
}
});
Object.getOwnPropertyDescriptor(person,‘corp‘);
person.promote=2;
person.salary; //60000

原型标签 _prototype_
class标签
var toString=Object.prototype.toString;
function getType(o){return toString.call(o).slice(8,-1);};
toString.call(null); //"[object Null]"
getType(null); //"null"
getType(new Number(1)); //"Number"
getType(1); //"Number"
Object.prototype.toString把参数变为对象再处理
typeof new Number(1); //"object"

extensible标签 是否可扩展 对象上的属性是否可以继续添加
var obj={x:1.y:2}
Object.extensible(obj);
Object.preventExtensions(obj);
Object.isExtensible(obj); // false
obj.z = 1;
obj.z; // undefined, add new property failed
Object.getOwnPropertyDescriptor(obj, ‘x‘);
// Object {value: 1, writable: true, enumerable: true, configurable: true}

Object.seal(obj);
Object.getOwnPropertyDescriptor(obj, ‘x‘);
// Object {value: 1, writable: true, enumerable: true, configurable: false}
Object.isSealed(obj); // true

Object.freeze(obj);
Object.getOwnPropertyDescriptor(obj, ‘x‘);
// Object {value: 1, writable: false, enumerable: true, configurable: false}
Object.isFrozen(obj); // true
这里提到的方法这是针对这个对象 不会影响原型链

序列化
JSON.stringfy
val:undefined 不会出现在序列化结果中
obj = {val : undefined, a : NaN, b : Infinity, c : new Date()};
JSON.stringify(obj); // "{"a":null,"b":null,"c":"2015-01-20T14:15:43.910Z"}"
JSON.parse(‘{"x":1}‘);

尝试把一个对象转化为值
toString还是valueOf取决操作符和特定情况
字符串拼接 toString
一元加好符 数字优先valueOf

数组是值得有序集合,每个值叫元素,没有元素都有数字位置编号,索引。js是弱类型的可以含有不同类型的元素 对象 数组

创建数组
字面量 var arr1=[,,] //undefined*2 这样不好
size from 0 to 4294967295 (2^23-1)
构造器 var arr=new Array(100); //undefined*100 new其实可以省略
数组元素读写
arr[5]=6;
delete arr[0] delete数组长度不变将元素变为undefined
数组元素增删 动态的 无需指定大小
arr[arr.length]=1 等价 arr.push(1) unshif()
arr.length-=1 pop() shift()
数组迭代
for(i=0;i<n;i++){}
无顺序for(i in arr){
if(arr.hasOwnProperty(i)){
}
}
二维数组
var arr=[[0,1],[2,3],[4,5]]; 遍历i,j for循环
稀疏数组
并不含有从0开始的连续索引 一般length属性比实际元素个数打
var arr1=[undefined]; var arr2=new Array(1);
0 in arr1; //true 有第0个元素undefined
0 in arr2; //false 长度为1
for in遍历的是key

数组方法
{} Object.prototype
[] Array.prototype
slice()切片 splice()胶接
join 将数组转为字符串 默认逗号分隔
function repeatString(str,n){
return new Array(n+1).join(str);
}
repeatString("a",3); //"aaa"
reverse() 将数组逆序 原数组也被修改
sort() 排序 默认按照字母顺序排序 原数组被修改
arr.sort(function(a,b){
return a-b;
});
concat() 数组合并 原数组未被修改
var arr=[1,2,3];
arr.concat([10,11],13); [1,2,3,10,11,13]
arr.concat([1,[2,3]]); [1,2,3,1,[2,3]]
slice 放回数组片段 左闭右开区间的元素 负数加length 元数组未修改
splice 数组拼接 返回切掉的元素 原数组被修改
arr[1,2,3,4,5];
arr.splice(1,1,‘a‘,‘b‘); //returns [2]
arr; // [1,"a","b",3,4,5]

ES5 ie9+
forEach() 数组遍历
arr.forEach(function(x,index,a){
console.log(x + ‘|‘ + index + ‘|‘ + (a===arr));
})
map() 数组映射 不修改原数组
arr.map(function(x){
return x+10;
})
filter() 数组过滤 不修改原数组
arr.filter(function(x,index){
return index % 3 === 0||x>=8;
})
every() some() 数组判断 验证数组中元素
reduce() 数组中元素两两操作 原数组未修改
var arr=[1,2,3];
arr.reduce(function(x,y){
return x+y;
},0); 0+1 1+2 3+3 参数0没有的话 1+2 3+3
reduceRight()
将数组聚合成一个结果
indexOf() 不存在 -1 arr.index(1,-3); 从-3位置开始查找1
lastIndexOf()
判断是否为数组
Array.isArray([]); //true 注意不在Array.prototype上不能直接isArray()
[] instanceof Array; true
({}).toString.apply([]) === ‘[object Array]‘; true
[].constructor === Array; true

数组和一般对象
相同
都可以继承
数组是对象,对象不一定是数组
都可以当做对象添加删除属性
不同
数组自动更新length
按索引访问数组常常比访问一般对象属性明显迅速。
数组对象继承Array.prototype上的大量数组操作方法

字符串和数组
字符串是类数组,但是是不可改写的writable:false
str.chaAt();
str[1];
Array.prototype.join.call(str,"_");

函数是一块javascript代码 被定义一次 但可以执行和调用多次 js的函数也是对象 可以像其它对象那样操作和传递
我们称js的函数为函数对象
一般函数调用没有return 默认返回undefined
new构造 如果没有返回或返回是基本类型 默认返回是this 如果返回对象则将其作为new操作的返回值

不同调用方式
直接调用 foo();
对象方法 o.method();
构造器 new Foo();
call/apply/bind func.call(o);

创建函数
函数声明
函数声明会被前置 可以在函数声明前调用 (函数声明和变量声明都有这个操作)
不允许匿名 不能立即调用(函数声明被前置提前解析)
在定义该函数的作用域通过函数名调用,而函数表达式和函数构造不行
函数表达式
(function(){})
return function(){}
赋值 命名式函数表达式 var add=function foo(a,b){};
命名式函数表达式
var func=function nfe(){};
alert(func===nfe);
ie6-8 false
ie9+ "nfe is undefined" nfe是访问不到的
调试时可以看到函数名
利用函数名递归调用 但是不常用

Function构造器 var function= new Function(‘a‘,‘b‘,‘console.log(a+b);‘); Function.prototype 不常见
构造器里面创建的变量是局部变量 外面拿不到
它可以拿到全局变量 但是拿不到包裹它的外层函数定义的局部变量
没有函数名

this
全局的this
浏览器下window this===window
一般函数的this
function f1(){return this}; f1()===window;//true,global object
"use strict" undefined
作为对象方法的函数this
不看函数是如何创建 看函数调用的方法
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
console.log(o.f()); // logs 37

对象原型链上的this
var o = {f:function(){ return this.a + this.b; }};
var p = Object.create(o);
p.a = 1;
p.b = 4;
console.log(p.f()); // 5

get/set方法与this
function modulus(){
return Math.sqrt(this.re * this.re + this.im * this.im);
}
var o = {
re: 1,
im: -1,
get phase(){
return Math.atan2(this.im, this.re);
}
};
Object.defineProperty(o, ‘modulus‘, {
get: modulus, enumerable:true, configurable:true});
console.log(o.phase, o.modulus); // logs -0.78 1.4142

构造器中this
call/apply方法与this
bind方法与this
function f(){
return this.a;
}
var g = f.bind({a : "test"});
console.log(g()); // test
var o = {a : 37, f : f, g : g};
console.log(o.f(), o.g());

函数属性和arguments
foo.name 函数名
foo.length 形参个数
arguments.length 实参个数
arguments是类数组对象 原型不是Array.prototype

function foo(x, y, z) {
arguments.length; // 2
arguments[0]; // 1
arguments[0] = 10; 绑定关系 严格模式下不起作用 arguments是传入参数的副本 改变不了原参数
x; // change to 10;
arguments[2] = 100; 未传参数失去绑定关系
z; // still undefined !!!
arguments.callee === foo; // true 严格模式下禁止使用
}
foo(1, 2);
foo.length; // 3
foo.name; // "foo"

call/apply方法
function foo(x, y) {
console.log(x, y, this);
}
foo.call(100, 1, 2); // 1, 2, Number(100)
foo.apply(true, [3, 4]); // 3, 4, Boolean(true)
foo.apply(null); // undefined, undefined, window
foo.apply(undefined); // undefined, undefined, window

function foo(x, y) {
‘use strict‘;
console.log(x, y, this);
}
foo.apply(null); // undefined, undefined, null
foo.apply(undefined); // undefined, undefined, undefined

bind与currying
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var getX = module.getX;
getX(); // 9
var boundGetX = getX.bind(module);
boundGetX(); // 81
函数柯理化
function add(a, b, c) {
return a + b + c;
}
var func = add.bind(undefined, 100); a绑定100
func(1, 2); // 103
var func2 = func.bind(undefined, 200); b绑定200
func2(10); // 310

bind与new

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。