了解语言特性最快的方式是调试诡异的代码
Paste_Image.png
补充1
<script>
var a=[1,2,3];
var b=a;
a=[4,5,6];
console.log(b);
//[1,2,3]
var a=[1,2,3];
var b=a;
a.pop();
console.log(b);
//[1,2]
</script>
补充2 this
<script>
function sayLocation() {
console.log(this.atWhere)
}
var atWhere = "I am in global";
sayLocation();
//I am in global
</script>
<script>
'use strict';
function sayLocation() {
console.log(this.atWhere);
}
var atWhere = "I am in global";
sayLocation();
// Uncaught TypeError
</script>
<script>
var name = "global";
function person() {
console.log(this.name);
//"global"
person.name = 'inside';
function sayName() {
console.log(this.name);
//"global"
}
sayName();
}
person();
</script>
<script>
function say() {
console.log(this.name);
}
var obj1 = {
name: "1",
say: say
}
var obj2 = {
name: "2",
say: say
}
obj1.say();
//1
obj2.say();
//2
</script>
<script>
function say() {
console.log(this.name);
}
var name = "global";
var obj = {
name: "inside",
say: say
}
obj.say();
//inside
var alias = obj.say;
alias();
//global
</script>
<script>
function speak() {
console.log(this.name);
}
var name = "global";
var obj1 = {
name: 'obj1'
}
var obj2 = {
name: 'obj2'
}
speak();
//global
speak.call(window);
//global
speak.call(obj1);
//obj1
speak.call(obj2);
//obj2
</script>
<script>
function count(x,y) {
console.log(this.a*x+y);
}
var obj1 = {
a: 2
}
var obj2 = {
a: 3
}
count.call(obj1, 1, 2)
//4
count.apply(obj1, [1, 2])
//4
count.call(obj2, 1, 2)
//5
count.apply(obj2, [1, 2])
//5
</script>
<script>
function count(x,y) {
console.log(this.a*x+y);
}
var obj1 = {
a:2
}
var bound1 = count.bind(obj1);
bound1(1, 2);
var bound2 = count.bind(obj1, 1);
bound2(2);
var bound3 = count.bind(obj1, 1, 2);
bound3();
var bound4 = count.bind(obj1, 1, 2, 3);
//指定了多余的参数,多余的参数会被忽略
bound4();
//4
</script>
<script>
function Person(name,age) {
this.name = name;
this.age = age;
console.log("f");
}
Person("n",0);
//f
console.log(name);
//n
console.log(age);
//0
var n=new Person("n",0);
//f
console.log(n.name);
//n
console.log(n.age);
//0
</script>
<script>
function speak() {
console.log(this.name);
}
var obj1 = {
name: 'obj1',
speak: speak
}
var obj2 = {
name: 'obj2'
}
obj1.speak();
//obj1
obj1.speak.call(obj2);
//obj2
</script>
<script>
function foo(something) {
this.a = something;
}
var obj1 = {};
var bar = foo.bind(obj1);
//返回一个新函数bar,这个新函数内的this指向了obj1
bar(2);
console.log(obj1.a);
//2
var baz = new bar(3)
//调用new 操作符后,bar函数的this指向了返回的新实例baz
console.log(obj1.a);
//2
console.log(baz.a);
//3
</script>
<script>
var a = 1;
var foo = () => {
console.log(this.a);
}
var obj = {
a: 2
}
foo();
//1
foo.call(obj);
//1
</script>
<script>
function Person(name,age) {
this.name = name
this.age = age
this.speak = function (){
console.log(this.name)
//普通函数
}
this.bornYear = () => {
//箭头函数
console.log(new Date().getFullYear() - this.age)
}
}
var n = new Person("n",10)
n.speak()
//'n'
n.bornYear()
//2007
var m = {
name: "m",
age: 100
}
n.speak.call(m)
//'m'
n.bornYear.call(m)
//2007
</script>
补充3:apply
<script>
function Person(name,age){
this.name=name;
this.age=age;
this.sayhello=function(){console.log("hello")};
}
function Print(){
this.funcName="Print";
this.show=function(){
var msg=[];
for(var key in this){
if(typeof(this[key])!="function"){
msg.push([key,":",this[key]].join(""));
}
}
console.log(msg.join(" "));
};
}
function Student(name,age,grade,school){
Person.apply(this,arguments);
Print.apply(this);
this.grade=grade;
this.school=school;
}
var p1=new Person("jake",10);
p1.sayhello();
var s1=new Student("tom",13,6,"清华小学");
s1.show();
s1.sayhello();
console.log(s1.funcName);
//hello
//name:tom age:13 funcName:Print grade:6 school:清华小学
//hello
//Print
</script>
<script>
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0];i<arrLen;i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
function getMax2(arr){
return Math.max.apply(null,arr);
}
var a=[1,2,3];
console.log(getMax(a));
console.log(getMax2(a));
//3
var arr1=[1,2,3];
var arr2=[4,5,6];
Array.prototype.push.apply(arr1,arr2);
console.log(arr1);
//[1,2,3,4,5,6]
</script>
《javascript权威教程》
//p37
//二进制浮点数
var x=.3-.2;
var y=.2-.1;
console.log(x==y);
//false
console.log(x==.1);
//false
console.log(y==.1);
//true
//p38
//日期
var then=new Date(2017,0,8);
//2017 1 14 周日
console.log(then.getMonth());
//0
console.log(then.getDate());
//8
console.log(then.getDay());
//0
//p40
//转义
console.log('you\'re right');
//p43
//object true
if(0!==null){
console.log('excute');
}
//excute
var o={};
if(o){
console.log('excute');
}
//excute
var o;
if(o){
console.log('excute');
}
//no excute
//p57
//全局变量
var global=this;
//p58
//包装对象
var s="s";
s.property='property';
alert(s.property);
//undefind
//显式创建包装对象
var s='string';
var S=new String(s);
console.log(S.length);
S.length=100;
console.log(S.length);
S.wtf="sonof";
console.log(S.wtf);
//6
//6
//sonof
//p59
var s='hello';
s.toUpperCase();
console.log(s.toUpperCase());
//HELLO
console.log(s);
//hello
s=s.toUpperCase();
console.log(s);
//HELLO
//p60
//数组、对象永不相等
var o1={x:1};
var o2={x:1};
console.log(o1==o2);
//false
var arr1=[1,2];
var arr2=[1,2];
console.log(arr1==arr2);
//false
<script>
//对象值都是引用
var a=[];
var b=a;
b[0]=1;
console.log(a[0]);
//1
console.log(b===a);
//true
</script>
<script>
//类型转换
console.log(10+'object');
//string '10object'
console.log('7'*'4');
//numeric 28
console.log(n=1-'x');
//NaN
console.log(n+'object');
//string NaNobject
</script>
<script>
//p62
//转换和相等性
console.log(null==undefined);
console.log('0'==0);
console.log(0==false);
console.log('0'==false);
//all true
</script>
<script>
//显式转换
console.log(Number(3));
//3
console.log(String(false));
//'false'
console.log(Boolean([]));
//true
console.log(Object(3));
//=>new Number(3);
</script>
<script>
//p67
var now=new Date();
console.log(now+1);
//string
console.log(now-1);
//number
console.log(now==now.toString());
//true
</script>
<script>
//p68
//不使用var,造成的作用域问题
var scope='global';
function checkscope(){
scope='local';
return scope;
}
checkscope();
console.log(scope);
//local
</script>
<script>
//p69
//函数作用域,非类c{}作用域
function test(){
var i=0;
if(1){
var j=0;
for(var k=0;k<10;k++){
//console.log(k);
}
console.log(k);
//10
}
console.log(j);
//0
}
test();
</script>
<script>
//p70
//删除全局变量
var truevar=1;
//不可删除全局“变量”
fakevar1=2;
//全局“对象”的一个可删除属性
this.fakevar2=3
//同fakevar1
console.log(delete truevar);
//false
console.log(delete fakevar1);
//true
console.log(delete fakevar2);
//true
</script>
<script>
//p75
var square=function(x){return x*x;}
console.log(square(2));
//4
</script>
<script>
//p83
console.log('1'+2);
//string '12'
console.log(1+{});
//string '1[object Object]'
console.log(true+true);
//2
console.log(2+null);
//2
console.log(2+undefined);
//NaN
</script>
<script>
//p84
var i=1,j=++i;
console.log(i);
//2
console.log(j);
//2
var i=1,j=i++;
console.log(i);
//2
console.log(j);
//1
</script>
<script>
//p87
//js对象比较是引用比较,不是值比较
var a=null;
var b=null;
console.log(a===b);
//true勘误
var a=undefined;
var b=undefined;
console.log(a===b);
//true勘误
var a=null;
var b=undefined;
console.log(a==b);
var a=NaN;
var b=NaN;
console.log(a==b);
console.log(a===b);
//false
console.log(a==a);
console.log(a===a);
//false
a={x:1,y:2};
b={x:1,y:2};
console.log(a==b);
console.log(a===b);
//false
var a=null;
var b=undefined;
console.log(a==b);
//true
console.log('1'==1);
//true
console.log(true==1);
//true
console.log(false==0);
//true
</script>
<script>
//p89
console.log('11'<'2');
//true
console.log('1'<2);
//true
console.log('one'<3)
//false 'one'->NaN<3
</script>
<script>
//p90
var p={x:1,y:1};
console.log('toString' in p);
//true
var d=[7,8,9];
console.log(7 in d);
//false
console.log(0 in d);
//true
console.log(3 in d);
//false
</script>
<script>
//p92
//短路
if(a==b) stop();
(a==b) && stop();
</script>
<script>
//p95
var i=0;
var data=[1,2];
data[i++]*=2;
console.log(data);
console.log(i);
//[2,2]
//1
var i=0;
var data=[1,2,3];
data[++i]*=2;
console.log(data);
console.log(i);
//[1,4,3]
//1
var i=0;
var data=[1,2];
data[i++]=data[i++]*2;
console.log(data);
console.log(i);
//[4,2]
//2
var i=0;
var data=[1,2,3];
data[++i]=data[++i]*2;
console.log(data);
console.log(i);
//[1,6,3]
//2
</script>
<script>
//96
//eval解释运行有js源代码组成的字符串
console.log(eval('3+2'));
//5
f=function(){
eval('function f(x){return x+1}');
return f(1);
}
console.log(f());
//2
</script>
<script>
//p97
var x='global';
function f(){
var x='local';
eval("x+=' changed'");
return x;
}
console.log(f(),x);
//local changed global
geval=eval;
var y='global';
function g(){
var y='local';
geval("y+=' changed'");
return y;
}
console.log(g(),y);
//local global changed
</script>
<script>
//p100
var o={x:1,y:2};
delete o.x;
console.log(o);
//{y:2}
var a=[1,2,3];
delete a[2];
console.log(a);
//[1,2]
console.log(a.length);
//3
var o={x:1,y:2};
console.log(delete o.x);
//true
console.log(typeof o.x);
//undefined
console.log(delete o.x);
//true 删除不存在的属性,返回true
console.log(delete o);
//false 不能删除通过var申明的变量
this.x=1;
console.log(delete x);
//true
console.log(x);
//运行时错误
</script>
<script>
//p117
var o={x:1,y:2,z:3};
var a=[],i=0;
for(a[i++] in o);
console.log(a);
//['x','y','z']
for(x in a) console.log(x);
//0 1 2
</script>
<script>
//p123
//阶层函数
function factorial(x){
if(x<0) throw new Error('x不能是负数');
for(var f=1;x>1;f*=x,x--);
return f;
}
try{
var n=Number(prompt('请输入一个正整数',''));
var f=factorial(n);
alert(n+'!='+f);
}
catch(ex){
alert(ex);
}
finally{}
</script>
<script>
//p126
/*
with(document.forms[0]){
name.value='';
address.value='';
email.value='';
}
*/
var o={x:1,y:2};
with(o) x=10;
console.log(o);
//{x:10,y:2}
</script>
<script>
//p126
//断点调试
function f(o){
if(o===undefined) debugger;
console.log('functon excute');
}
f();
</script>
<script>
//p134
//通过原型继承创建一个新对象
function inherit(p){
if(p==null) throw TypeError();
if(Object.create)
return Object.create(p);
var t=typeof p;
if(t!=="object" && t!=="function") throw TypeError();
function f(){}
f.prototype=p;
return new f();
}
//防止对o的意外修改
var o={x:'dont\'t change this value};
library_function(inherit(o));
</script>
<script>
//137
//通过原型继承创建一个新对象
function inherit(p){
if(p==null) throw TypeError();
if(Object.create)
return Object.create(p);
var t=typeof p;
if(t!=="object" && t!=="function") throw TypeError();
function f(){}
f.prototype=p;
return new f();
}
var o={};
o.x=1;
var p=inherit(o);
p.y=2;
var q=inherit(p);
q.z=3;
console.log(q.x);
console.log(q.y);
console.log(q.z);
</script>
//138
//通过原型继承创建一个新对象
function inherit(p){
if(p==null) throw TypeError();
if(Object.create)
return Object.create(p);
var t=typeof p;
if(t!=="object" && t!=="function") throw TypeError();
function f(){}
f.prototype=p;
return new f();
}
var unitcircle={r:1};
var c=inherit(unitcircle);
c.r=2;
console.log(unitcircle.r);
//1
<script>
//p138
var book={subtitle:{length:100}}
var len=undefined;
if(book){
if(book.subtitle) len=book.subtitle.length;
}
console.log(len);
//100
var book={subtitle:{length:100}}
var len=undefined;
len=book && book.subtitle && book.subtitle.length;
console.log(len);
//100
</script>
<script>
//p140
function inherit(p){
if(p==null) throw TypeError();
if(Object.create)
return Object.create(p);
var t=typeof p;
if(t!=="object" && t!=="function") throw TypeError();
function f(){}
f.prototype=p;
return new f();
}
var p={x:1};
var q=inherit(p);
p.y=2;
console.log(p);
//{x:1,y:2}
console.log(q);
//{x:1,y:2}
console.log(delete q.y);
//true
console.log(q);
//{x:1,y:2}
q.z=3;
console.log(p);
//{x:1,y:2}
</script>
<script>
//p140
var x=1;
console.log(delete this.x);
//false
console.log(x);
//1
function f(){};
console.log(delete this.f);
//false
this.y=1;
console.log(delete y);
//true
console.log(y);
//undefined error
</script>
<script>
var o={x:1,y:1};
function d(){
var o={x:2,y:2};
delete o.x;
console.log(o);
}
d();
//{y:2}
</script>
<script>
//p141
function inherit(p){
if(p==null) throw TypeError();
if(Object.create)
return Object.create(p);
var t=typeof p;
if(t!=="object" && t!=="function") throw TypeError();
function f(){}
f.prototype=p;
return new f();
}
var o=inherit({y:2});
o.x=1;
console.log('x' in o);
//true
console.log(o.propertyIsEnumerable('x'));
//true
console.log(o.hasOwnProperty('x'));
//true
console.log('y' in o);
//true
console.log(o.propertyIsEnumerable('y'));
//false
console.log(o.hasOwnProperty('y'));
//false
//继承而来不可枚举
</script>
<script>
//p142
for(p in o){
if(!o.hasOwnProperty(p)) continue;//跳过继承的属性
}
for(p in o){
if(typeof o[p]==='function') continue;//跳过方法
}
</script>
<script>
//p142
function extend(o,p){
for(prop in p){
o[prop]=p[prop];
}
return o;
}
var o={};
var p={x:1,y:2};
console.log(extend(o,p));
//{x:1,y:2}
p.z=3;
console.log(o);
//{x:1,y:2}
var p={x:1,y:2};
var o=p;
console.log(o);
//{x:1,y:2}
p.z=3;
console.log(o);
//{x:1,y:2,z:3}
</script>
<script>
//p143
function merge(o,p){
for(prop in p){
if(o.hasOwnProperty[prop]) continue;
o[prop]=p[prop];
}
}
function restrict(o,p){
for(prop in o){
if(!(prop in p)) delete o[prop];
}
return o;
}
function union(o,p){return extend(extend({},o),p)}
//extend{o,p} if coding like this,o changed
function intersection(o,p){return restrict(extend({},o),p)}
</script>
<script>
//p144
function keys(o){
if(typeof o !=='object') throw TypeError();
var result=[];
for(var prop in o){
if(o.hasOwnProperty(prop))
result.push(prop);
}
return result;
}
//keys()类似于Object.keys() Object.getOwnPropertyNames()
</script>
<script>
//145
function inherit(p){
if(p==null) throw TypeError();
if(Object.create)
return Object.create(p);
var t=typeof p;
if(t!=="object" && t!=="function") throw TypeError();
function f(){}
f.prototype=p;
return new f();
}
var p={
x:1.0,
y:1.0,
get r(){return Math.sqrt(this.x*this.x+this.y*this.y);},
set r(newvalue){
var oldvalue=Math.sqrt(this.x*this.x+this.y*this.y);
var ratio=newvalue/oldvalue;
this.x*=ratio;
this.y*=ratio;
},
get theta(){return Math.atan2(this.y,this.x);}
};
var q=inherit(p);
q.x=1,q.y=1;
console.log(q.r);
console.log(q.theta);
var serialnum={
$n:0,
get next(){return this.$n++;},
set next(n){
if(n>=this.$n){
this.$n=n;
}else{
throw '< illegal';
}
}
}
snum=inherit(serialnum);
console.log(snum.next);
//0
console.log(snum.next);
//1
snum.next=-99;
//error < illegal
</script>
<script>
//p147
var o={};
Object.defineProperty(o,'x',{
value:1,
writable:true,
enumerable:false,
configurable:true});
console.log(o.x);
//1
console.log(Object.keys(o));
//[]不可枚举
Object.defineProperty(o,'x',{
writable:false
});
console.log(o.x=2);
//2
console.log(o.x);
//1
Object.defineProperty(o,'x',{
value:2
});
console.log(o.x);
//2
//只读,但是可配置configurable
Object.defineProperty(o,'x',{
get:function(){return 0}
});
console.log(o.x);
//0
</script>
<script>
//p148
var p=Object.defineProperties({},{
x:{value:1,writable:true,enumerable:true,configurable:true},
y:{value:1,writable:true,enumerable:true,configurable:true},
z:{
get:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},
enumerable:true,
configurable:true
},
});
</script>
<script>
//149
//?
Object.defineProperty(Object.prototype,
'extend',
{
writable:true,
enumerable:false,
configurable:true,
value:function(o){
var names=Object.getOwnPropertyNames(o);
for(var i=0;i<names.length;i++){
if(names[i] in this) continue;
var desc=Object.getOwnPropertyDescriptor(o,names[i]);
Object.defineProperty(this,names[i],desc);
}
}
})
</script>
<script>
var p={x:1};
var o=Object.create(p);
console.log(p.isPrototypeOf(o));
//true
console.log(Object.prototype.isPrototypeOf(p));
//true
function classof(o){
if(o===null) return 'Null';
if(o===undefined) return 'Undefined';
return Object.prototype.toString.call(0).slice(8,-1);
}
//Object.preventExtensions()
//Object.seal()
//Object.freeze()
</script>
<script>
//p151
var p={x:1};
var o=Object.create(p);
console.log(p.isPrototypeOf(o));
//true
console.log(Object.prototype.isPrototypeOf(p));
//true
function classof(o){
if(o===null) return 'Null';
if(o===undefined) return 'Undefined';
return Object.prototype.toString.call(0).slice(8,-1);
}
//Object.preventExtensions()
//Object.seal()
//Object.freeze()
o={x:1,y:{z:[false,null,'']}};
s=JSON.stringify(o);
p=JSON.parse(s);
</script>
<script>
//168
var data=[1,2,3,4,5];
data.forEach(function(v,i,a){a[i]=v+1;});
console.log(data);
//170
var a=[1,2,3,4,5];
var sum=a.reduce(function(x,y){return x+y},0);
console.log(sum);
//15
var product=a.reduce(function(x,y){return x*y},1);
console.log(product);
//120
var max=a.reduce(function(x,y){return x>y?x:y});
console.log(max);
//5
//p171
var a=[2,3,4];
var fn=function(accumulator,value){
return Math.pow(value,accumulator);
};
console.log(a.reduceRight(fn));
console.log(a.reduce(fn));
</script>
<script>
//p172
function extend(o,p){
for(prop in p){
o[prop]=p[prop];
}
return o;
}
function union(o,p){return extend(extend({},o),p)}
var objects=[{x:1},{y:2},{z:3}];
var merged=objects.reduce(union);
console.log(merged);
//{x:1;y:2;z:3}
var objects=[{x:1,a:1},{y:2,a:2},{z:3,a:3}];
console.log(objects.reduce(union));
//{x:1,y:2,z:3,a:3}
console.log(objects.reduceRight(union));
//{x:1,y:2,z:3,a:1}
</script>
<script>
//172
a=[1,1,2,1,0,1];
console.log(a.indexOf(1));
//0
console.log(a.indexOf(1,1));
//1
console.log(a.lastIndexOf(1));
//5
console.log(a.indexOf(3));
//-1
function findall(a,x){
var results=[],
len=a.length,
pos=0;
while(pos<len){
pos=a.indexOf(x,pos);
if(pos===-1) break;
results.push(pos);
pos=pos+1;
}
return results;
}
console.log(findall(a,1));
//[0,1,3,5]
</script>
<script>
//175
var a={'0':'a','1':'b','2':'c',length:3};
console.log(Array.prototype.join.call(a,"+"));
//'a+b+c'
console.log(Array.prototype.slice.call(a,0));
//['a','b','c']
console.log(Array.prototype.map.call(a,function(x){
return x.toUpperCase();
}));
//['A','B','C']
var s='test';
console.log(s.charAt(0));
//t
console.log(s[1]);
//e
s='Javascript';
console.log(Array.prototype.join.call(s,' '));
//J a v a s c r i p t
console.log(Array.prototype.filter.call(s,
function(x){
return x.match(/[^aeiou]/);
}).join(''));
//Jvscrpt
</script>
<script>
//p178
function factorial(x){
if(x<=1) return 1;
return x*factorial(x-1);
}
var calculator={
operand1:1,
operand2:1,
add:function(){
this.result=this.operand1+this.operand2;
}
};
calculator.add();
console.log(calculator.result);
//2
</script>
<script>
//p183
var o={
m:function(){
var self=this;
console.log(this===o);
f();
function f(){
console.log(this===o);
console.log(self===o);
}
}
};
o.m();
//true
//false
//true
</script>
<script>
//p185
function getPropertyNames(o,a){
if(a===undefined) a=[];
//a=a || [];
for(var property in o) a.push(property);
return a;
}
function f(x,y,z){
if(arguments.length!=3){
throw new Error('function f called with'+arguments.length+'arguments,but it expects 3 arguments');
}else{
console.log('execute');
}
}
f(1,2,3);
f(1,2);
</script>
<script>
//p186
console.log(Number.NEGATIVE_INFINITY);
//-INFINITY
function max(){
var max=Number.NEGATIVE_INFINITY;
for(var i=0;i<arguments.length;i++){
if(arguments[i]>max){max=arguments[i]}
}
return max;
}
console.log(max(1,2,3,4,5,6,7));
//p187
function f(x){
console.log(x);
arguments[0]=null;
console.log(x);
}
f(1);
//p188
var factorial=function(x){
if(x<=1) return 1;
return x* arguments.callee(x-1);
//callee
}
console.log(factorial(3));
//p188
function arraycopy(from,from_start,to,to_start,length){
for(f in from){
if(f>=from_start && f<from_start+length){
to[to_start+(f-from_start)]=from[f];
}
}
return to;
}
function easycopy(args){
return arraycopy(args.from,
args.from_start || 0,
args.to,
args.to_start || 0,
args.length);
}
console.log(easycopy({from:[1,2,3,4,5,6,7],from_start:2,to:[],to_start:4,length:2}));
</script>
网友评论