HTML5 <iframe> 的 sandbox 属性以及 X-Frame-Options

HTML5 <iframe> sandbox

值    描述
""(为空)    应用以下所有的限制。
allow-same-origin    允许 iframe 内容被视为与包含文档有相同的来源。
allow-top-navigation    允许 iframe 内容从包含文档导航(加载)内容。
allow-forms    允许表单提交。
allow-scripts    允许脚本执行。

<iframe src="xxxx" sandbox="value">

当别人要frame你的网页时候,只要用sandbox不写”allow-script”时,即使页面写了下面代码,也不能防止别人frame。因为js根本不会执行。但是,css,html,form行为还是可以用的。

if(top.location!=self.location){
   top.location=self.location;
}

解决办法X-Frame-Options

好在可以采用 HTTP头X-Frame-Options解决问题。可以设置以下3个值。

  • DENY:—————浏览器会拒绝当前页面加载任何 frame 页面
  • SAMEORIGIN:———frame页面的地址只能为同源域名下的页面
  • ALLOW-FROM origin:–则可以定义允许 frame 加载的页面地址

IE8+都支持。一般设置成SAMEORIGIN就OK

webpack、react-router、react-router-loader

用bundle-loader,死活都不行,代码如下。按理来说,应该可以的,可能react-router更新了的关系

const loadContainerAsync = bundle => (location, cb) => {  
    bundle(component => {
        cb(null, component);
    });
};

render((  
    <Router history={hashHistory}>
        <Route path="/" component={App}>
            <IndexRoute component={Home} />
            <Route path="home" component={Home} />
            <Route path="addcase"  getComponent={loadContainerAsync(require('bundle?lazy!./Components/addcase.js'))}/>
            <Route path="casequery" component={casequery} />
            <Route path="usermanage" component={usermanage} />
            <Route path="datastat" component={datastat} />
            <Route path="Shegengku" component={Shegengku} />
            <Route path="VosQuery" component={VosQuery} />


        </Route>
    </Router>
), document.getElementById('body'));

最后使用react-router-loader才解决。

版本"react-router": "^2.4.0",

Installation

npm install react-router-loader –save-dev

<Route component={require('react-router!./Components/addcase.js')} />
<Route component={require('react-router?name=chunkName!./Components/addcase.js')} />

更加详细

Bootstrap的滚动条

setTimeout(function(){
document.getElementsByTagName(‘style’)[0].innerHTML+=’@-webkit-keyframes progress-bar-stripes {from {background-position: 40px 0;}to {background-position: 0 0;}}@-o-keyframes progress-bar-stripes {from {background-position: 40px 0;}to {background-position: 0 0;}}@keyframes progress-bar-stripes {from {background-position: 40px 0;}to {background-position: 0 0;}}.run{animation-delay: 0s; /???????????????????????/animation-direction: normal; /????????????????????????/animation-duration: 2s; /???????????????????/animation-fill-mode: none;animation-iteration-count: infinite; /???????????????/animation-name: progress-bar-stripes;/????? @keyframes ??????????????????/animation-play-state: running;animation-timing-function: linear; /??????????????????,????????? “ease”???/}.progress{background-color: rgb(92, 184, 92);background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.14902) 50%, rgba(255, 255, 255, 0.14902) 75%, transparent 75%);/* background-image: linear-gradient(45deg,rgba(255, 0, 255, 0.14902) 0%, rgba(255, 0, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 0, 255, 0.14902) 50%, rgba(255, 0, 255, 0.14902) 75%, transparent 75%, transparent 100%); */background-size: 40px 40px;color: rgb(255, 255, 255);transition-delay: 0s;transition-duration: 0.6s;transition-property: width;transition-timing-function: ease;border-radius:20px}’
},500)

        <style>       
        body{padding: 0;margin: 0;}
                @-webkit-keyframes progress-bar-stripes {
            from {
                background-position: 40px 0;
            }
            to {
                background-position: 0 0;
            }
        }
        @-o-keyframes progress-bar-stripes {
            from {
                background-position: 40px 0;
            }
            to {
                background-position: 0 0;
            }
        }
        @keyframes progress-bar-stripes {
            from {
                background-position: 40px 0;
            }
            to {
                background-position: 0 0;
            }
        }
        .run{
            animation-delay: 0s;    /*动画延迟加载时间*/
            animation-direction: normal;   /*重复方向,可逆向*/
            animation-duration: 2s;     /*重复间隔时间。*/
            animation-fill-mode: none;
            animation-iteration-count: infinite;  /*重复次数。*/
            animation-name: progress-bar-stripes;/*规定 @keyframes 动画的名称。*/
            animation-play-state: running;
            animation-timing-function: linear; /*动画速度曲线,默认是 "ease"。*/
        }
         .progress{
            background-color: rgb(92, 184, 92);
            background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.14902) 50%, rgba(255, 255, 255, 0.14902) 75%, transparent 75%);
   /*  background-image: linear-gradient(45deg,rgba(255, 0, 255, 0.14902) 0%, rgba(255, 0, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 0, 255, 0.14902) 50%, rgba(255, 0, 255, 0.14902) 75%, transparent 75%, transparent 100%); */
            background-size: 40px 40px;
            color: rgb(255, 255, 255);

            transition-delay: 0s;  /*CSS3 过渡*/
            transition-duration: 0.6s;
            transition-property: width;
            transition-timing-function: ease;

            border-radius:20px

        }
        </style>
<div style="height: 40px;width: 800px;" class="progress run"></div>  

原理很简单:

  • background-color: rgb(92, 184, 92)绿色;在下面,用background-image形成透明条纹。
  • background-image: linear-gradient(45deg,rgba(255, 0, 255, 0.14902) 0%, rgba(255, 0, 255, 0.14902) 25%, transparent 25%, transparent 50%, rgba(255, 0, 255, 0.14902) 50%, rgba(255, 0, 255, 0.14902) 75%, transparent 75%, transparent 100%); 这个意思是,倾斜45度,0%-25%,rgba(255, 0, 255, 0.14902)这个颜色,25%-50%,transparent 透明,50%-75%又是这个颜色,75%-100%透明。0%和100%是可以省略的。

3D-笔记1

今天,买了OpenGl ES2.0游戏开发,上下两卷。花了158大洋。开始系统地学习3D。

float k=1 错误,glsl语言并不会,把整数1转浮点1.0

//混合选择
vec4 color = vec3(0.7,0.1,0.5,1.0) //rgba  
vec3 temp = color.agb  //temp=(1.0,0.1,0.5)  
vec3 tempL;  
tempL.grb = color.aab //tempL=(0.7,0.7,0.1)  

mat3 md=mat3(2.0)

声明的是mat3(2.0,0.0,0.0,0.0,2.0,0.0,0.0,0.0,2.0),并不是全部赋值2.0

lowp mediump highp 3种精度

precision mediump float 定义全局精度。

attribute:一般用于每个顶点都不同的量,如顶点颜色,位置。

uniform:一般用于对一组顶点组成单个3D物体都相同的量,如光源位置。

varying:用于从顶点着色其传递到片元着色器的量。

const:用于声明常量。

attribute vec3 aPosition;//顶点位置  
attribute vec3 aNormal;//顶点法  
attribute vec2 aTexCoor;//顶点纹理坐标  

顶点着色器:输出变量

gl_Position:经过变换矩阵变换,投影后的顶点位置。  
gl_PointSize:指点的大小。  

片元着色器:内建输人变量

gl_FragCoord:(vec4)含有当前片元相当于窗口位置的坐标值x、y、z、1/w。其中x、y分别为片元相对于窗口的二维坐标,z为该片元的深度值。  
gl_FrontFacing:(bool)通过读取该内建变量的值可以判断正在处理的片元是否属于在光栅化阶段生成的此片元的对应图元的正面。一般用于开发双面光照功能相关的应用程序中。 

片元着色器:内建输出变量

gl_FragColor:(vec4)指计算后,此片元的颜色。此颜色值将送人渲染管线中的后继过程进行处理。  
gl_FragData:(vec4数组)写入时要给入下标:如gl_FragData[0],通过其写入的信息将供渲染管线中的后继过程使用。  
//实际开发中,对上述两个内建输出变量赋值时,应该根据具体情况选择其中一个,不应该同时对两个都进行赋值,若执行了discard操作,则两个内建变量都不需要写入值了。

varying:在顶点着色器赋值后并不是将赋的值送人片元着色器,而是在光栅化阶段由管线根据片元所属图元各个顶点对应的顶点着色器对此易变变量的赋值情况及片元与各顶点的位置关系插值产生。

js--call、apply、bind

先科普一下

var A = function(){  
console.log(this===window)  
}
A() // true this是window  
new A()//false 这里this是A的一个实例this instanceof A  :true  

一个函数执行和把它当构造函数执行是完全不同的,比如A()和new A()一样。

一个函数的上下文this从外层拿,外层没有就到更外层,反正在全局环境中this=window。

1.call和apply

call:改变上下文this,并执行函数,apply也是一样。
var fn=function(arg1,arg2){} fn.call(obj,arg1,arg2)

把obj这个对象,当做fn函数的this。并执行fn()

function add(a,b)  
{  
  alert(this.name);  
}  
var obj={name:'我是obj'}  
add.call(obj,3,1);//等于add.apply(obj,[3,1]);  

同理apply只是把fn参数,放在一个数组中。

这样可以用来实现继承:

function Animal(name){  
  this.name = name;      
  this.showName = function(){      
    alert(this.name);      
  }      
}      
function Cat(name){  
  Animal.call(this, name);  //把Animal中的this换成Cat的实例(this)。并执行Animal。    
}      
var cat = new Cat("Black Cat");  
cat.showName();  

2.bind

bind和call只有一点区别,都改变上下文this,但是bind不执行,而是返回改变this后的函数。

var temp=(function add(a,b)  
{  
  alert(this.name);  
}).bind({name:'我是obj'}) 
temp();  

bind不仅可以改变this。还可以绑定参数。

var add=function(a,b){ console.log(a,b); alert(this.name); }  
var temp=add.bind({name:'我是obj'},1);  
temp(3);    //输出1,3  
var temp2=add.bind({name:'我是obj'},8,9);  
temp2(1,3)  //输出8,9  

总结,call、apply、bind这些改变一个函数this的用法,还是很有用的。不然,就要把this用变量保存,利用函数作用域来,把this传入函数。

function Cat(name){  
    this.name=name;
    this.age=0;
    setInterval(function(){
         this.age++
    },1000)
}
var cat=new Cat('花花');  

乍一看,这个实例cat的年龄是一秒加1;但是setInterval(function(){this.age++},1000)中的this是指window。不是cat(匿名函数的this一般指向window,setInterval=window.setInterval)。

function Cat(name){  
    this.name=name;
    this.age=0;
    setInterval(function(){
         this.age++
    }.bind(this),1000)
}
var cat=new Cat('花花');这只猫的年龄,终于随时间增长了  
/////////
function Cat(name){  
    this.name=name;
    this.age=0;
    var that=this;
    setInterval(function(){  
         that.age++
    },1000)
}
var cat=new Cat('花花')//这样也行  
/////////
function Cat(name){  
    this.name=name;
    this.age=0;
    var that=this;
    setInterval(()=>{  
         that.age++
    },1000)
}
var cat=new Cat('花花')//箭头函数自动绑定了this  

js两种声明函数

  • function a(){}
  • var b=function(){}

1.第一种比第二种,多了提升(Hoisting)效果。

a();  
function a(){};这样是可以的。而第二种不行。  

2.第一种声明,还声明另一个属性name。

function a(){};  
console.log(a.name);  //a  
var b=function(){}  
console.log(b.name);  //''  

3.在直接赋值给另外的变量的时候。

var a,b;  
a=b=function(){};  
console.log(b)   //定义了

var c=function d(){console.log(d);};  
c();  //输出d  
console.log(d)  //d is not defined(…)  
等于
var c=(function(){  
    var d=function(){console.log(d)}
    return d;
})();

4.不要在一个非函数代码块(if、while 等)中声明一个函数用function test(){}。浏览器允许你这么做,但它们的解析表现不一致。

因为有些浏览器不用管if,直接就声明了。

if (true) {  
  function test() {
    console.log('true');
  }
}else{
  function test() {
    console.log('false');
  }
}
test();  //在ie8下输出'false';  
//////
var test;  
if (true) {  
   test =function () {
    console.log('true');
  }
}else{
  test =function () {
    console.log('false');
  }
}
test();  //最好的写法。  

vsftpd--经验

根据百度经验上面,可以连接上。但是,不能传文件。

  • 550 Permission denied

原因:vsftp默认配置不允许上传文件。

解决:修改/etc/vsftpd.conf

将“write_enable=YES”前面的#取消。

重启vsftp服务器。

  • 553 Could not create file 复制文件到远端时错误。

按照网上的做法,对/var/ftp目录进行权限设置,如果设置为chmod -R 777 /var/ftp

还会导致ftp服务器不能启动,经过摸索,终于找到了解决的方法。

首先在ftp的目录中创建一个目录,然后设置权限为777

$sudo mkdir /var/ftp/write

$sudo chmod -R 777 /var/ftp/write

然后修改vsftp的配置文件/etc/vsftpd.conf文件的最后添加上

local_root=/var/ftp

保存,然后杀死vsftpd进程,然后重启vsftpd服务器程序。sudo service vsftpd restart(ubuntu)

将文件上传到/var/ftp/write目录,这个时候可以正常的上传文件了。

一句话,改权限。改了权限的路径才能上传文件。sudo chmod -R 777 url

ES6--Proxy

Proxy 对象用来为基础操作(例如:属性查找、赋值、枚举、方法调用等)定义用户自定义行为。

用法

var p = new Proxy(target, handler);

var p = new Proxy({}, {  
    set: function(target, key, value, receiver) {
    console.log('method:set oldValue: '+target[key]+' newValue '+ value);
    target[key]=value;
    },
    get:function(target, key, receiver){
    console.log('method:get value '+target[key]);
    return target[key];
    },
    has:function(obj,key){
    return true;
    }
})
    p.name='123'  //调用set
        p.name  //调用set
        'aa' in p //调用has

这里只举了set,get,has这三种常用trap的例子,其实还有其他十几种trap,可以在MDN上查。

还有一种特殊的、针对函数的apply

var p = new Proxy(function(){}, {  
  apply: function(target, thisArg, argumentsList) {
     console.log('apply',argumentsList)//argumentsList函数的参数
  }
});
p('a','b')//执行apply  

利用这个可以写一些特殊函数,看起来很hack:

   var restfulize=function(str){
    var temp=function(){}
    temp.path=str;
    return new Proxy(temp,{
    get:function(target, name){
         target.path+='/'+name;
         return restfulize(temp.path);
    },
    apply:function(target, that, args){
        return target.path
    }
   })
 }

 var q= restfulize('https://api.github.com') 
 q.name
 q.abc
console.log(q.abc.qwe());//https://api.github.com/name/abc/abc/qwe

还可以加上一句console.log(arguments.callee.caller),可以看到各种行为是被那个函数调用的。

var p = new Proxy({}, {  
    set: function(target, key, value, receiver) {
         console.log(arguments.callee.caller)
    },
    get:function(target, key, receiver){
          console.log(arguments.callee.caller)
    }
})
function abc(){  
p.name='99999';  
}
abc();  //输出abc函数=》在abc中,p被赋值了。用来调试,一下就是找到问题所在。

注意:如果在全局被调用则输出null;

Hammer.js--移动端Web手势

Hammer.js是一个开源的,轻量级的javascript库,它可以在不需要依赖其他东西的情况下识别触摸,鼠标事件。

API如下

默认设置下自动添加了,tap、press,pan与swipe的横向滑动。

pinch和rotate识别器在默认情况下都是禁用的,因为他们会有元素阻塞,但是我们可以手动开启:

hammertime.get('pinch').set({ enable: true });  
hammertime.get('rotate').set({ enable: true });  

当然,我们还可以为pan与swipe 开启纵向滑动

hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL }); //全方向  
hammertime.get('swipe').set({ direction: Hammer.DIRECTION_VERTICAL }); //竖直方向  

我们能通过meta的标记,禁用doubletap/触控放大。但是新的浏览器支持touch-action属性所以可以不需要这个

还有一个demo

  • 轻触变红
  • 长触变绿
  • 单指拖动
  • 双指缩放,旋转(需要触屏设备)

高斯模糊

高斯模糊原理:

“模糊”,可以理解成每一个像素都取周边像素的平均值。

1   1   1     左边矩阵中,2是中间点,周边点都是1。"中间点"取"周围点"的平均值,就会变成1。  
1   2   1     在数值上,这是一种"平滑化"。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。  
1   1   1     显然,计算平均值时,取值范围越大,"模糊效果"越强烈。  

如果使用简单平均,显然不是很合理,因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。

正态分布(高斯分布)的权重

二维高斯函数

e:当n→∞时,(1+1/n)^n的极限,自然对数的底数,是一个无限不循环小数,其值是2.71828…

下面是一个二维高斯函数3d模型(使用playcanvas引擎,建立的曲面):

可见中间权重大,越到外面,约等于0;

var loadImage=function(url,callback){
    if(callback===undefined){
        callback=function(){};
    }
      var img = new Image(); //????????????Image????????????????????????????????
  img.src = url;
  if (img.complete) { // ??????????????????????????????????????????????????????????????????
        callback(img);
        return;
  }
  img.onload = function () { //????????????????????????????????callback?????????
       callback(img);
  };
   return img;
 }

var img=loadImage(‘/source/images/bg1.jpg’)

Wildcard Matching--LeetCode

Implement wildcard pattern matching with support for ‘?’ and ‘*’.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") ??? false
isMatch("aa","aa") ??? true
isMatch("aaa","aa") ??? false
isMatch("aa", "*") ??? true
isMatch("aa", "a*") ??? true
isMatch("ab", "?*") ??? true
isMatch("aab", "c*a*b") ??? false

题意:通配符匹配

?表示:任意字符。*表示:0个或者n个? 先自己写。用的循环。

var isMatch = function(s, p) {
    if(p==='*'){return true;}
    var j=0;
    var next;
    var isXin=false;
    var isSuccess=false;
    var toI;
    var toJ;
    var begin;
    for(var i=0;i<s.length;i++){
        var charI= s.charAt(i);
        var charJ= p.charAt(j)
        if(charI===charJ||charJ==='?'){
            if(charI!=next&&next!==undefined&&next!='?'){
                toI=toI+1;
            }else{
                if(charI==next||next=='?'){
                    begin=toI;
                }
            }
            j++;
            isSuccess=true;
            continue;
        }else{
            if(charJ==='*'){
                isXin=true;
                var toJ=j;
                var toI=i;
                next= p.charAt(j+1)
                while(next==='*'){
                    j++;
                    next=p.charAt(j+1);
                }
                if(next==''){return true;}
                if(charI===next||next==='?'){
                    isSuccess=true;
                    j=j+2;
                    begin=toI;
                }else{
                    isSuccess=false;
                }
                continue;
            }

            if(isXin){
                if(isSuccess){
                    j=toJ;
                    i=toI;
                    if(begin!=null){
                        i=begin;
                        begin=null;
                    }
                    isXin=false;
                }
            }else{
                return false;
            }
        }
    }
    var str= p.slice(j, p.length)
    if(str==''){return true;}
    if(!!str.match(/^\*+$/)&&isSuccess){return true}else{
        return false;
    }
};Runtime: 236 ms

在网上看到一个C语言的版本,C语言还是快,11ms运行时间.

bool isMatch(const char *s, const char *p) {
    const char* star = NULL;
    const char* ss = s;
    while (*s) {
        if ((*p == '?') || (*p == *s)) { s++;p++;continue; }
        if (*p == '*') { star = p++; ss = s;continue; }
        if (star) { p = star + 1; s = ++ss;continue; }
        return false;
    }
    while (*p == '*') { p++; }
    return !*p;
}Runtime: 11 ms

改成javascript,思想和自己写的差不多。

var isMatch = function(s, p) {
    var i=0;var j=0;var k=0;var l=0;
    var star;
    var ss=s;
    while (s.charAt(i)){
        if ((p.charAt(j)=='?')||(p.charAt(j)==s.charAt(i))){i++;j++;continue;}
        if (p.charAt(j)=='*'){
            star=p.slice(j, p.length);
            j++;
            ss= s.slice(i, s.length);
            k=0;l=0;continue;
        }
        if (star){
            p= star.slice(k+1,star.length);
            j=0;
            l++;
            s=ss.slice(l,ss.length);
            i=0;
            continue;            
        }
        return false;
    }
    while (p.charAt(j)=='*'){j++;}
    return !p.charAt(j);
};Runtime: 264 ms 

第一个版本太乱了,虽然通过了。看了别人的解,这个题只需4个变量记录就可以了,修改如下:

var isMatch = function(s, p) {
      var toI=-1        //保存 出现*时,i的值。要是s.charAt(toI)未匹配成功,则从下一位开始匹配(toI++;),因为*可以为[0-n]个任意字符
      var toJ=-1;       //保存 出现*时,j的值,用于*后面匹配不成功时,回溯。
      var j=0;
      for(var i=0;i< s.length;i++){
          var CharI=s.charAt(i)
          var CharJ=p.charAt(j)
          if ((CharJ=='?')||(CharJ==CharI)){j++;continue;}
          if (CharJ=='*'){
              toJ=j;
              j++;
              toI=i;
              i--;
              continue;
          }
          if (toJ>=0){
              toI++
              i=toI;
              i--;
              j=toJ;
              j++;
              continue;            //        p = star+1; s=++ss;continue;
          }
          return false;
      }
      while (p.charAt(j)=='*'){j++;} //p最后的*全不要。
      return !p.charAt(j);    //j=p.lenght  P全部匹配完成。则return !""
  };Runtime: 256 ms

Text Justification

Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ‘ ‘ when necessary so that each line has exactly L characters.

Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

For the last line of text, it should be left justified and no extra space is inserted between words.

#######For example:

words: ["This", "is", "an", "example", "of", "text", "justification."]
L: 16.

Return the formatted lines as:
[
   "This    is    an",
   "example  of text",
   "justification.  "
]
Note: Each word is guaranteed not to exceed L in length.

题意:把一个集合的单词按照每行L个字符放,每行要两端对齐,如果空格不能均匀分布在所有间隔中,那么左边的空格要多于右边的空格,最后一行靠左对齐。

var fullJustify = function(words, maxWidth) {
     if(maxWidth===0){return [''];}
     function packSpace(size){
         str='';
         for(var i=0;i<size;i++){
             str+=' ';
         }
         return str;
     }
     var result=[];
     var sum=0;
     var index=0;
     for(var i=0;i<words.length;i++){
         sum=sum+words[i].length+1;
         if(sum-1>maxWidth){
             var size=i-index-1;
             var l=sum-words[i].length-size-2    
             var spaceSize = Math.floor((maxWidth-l)/(size));
             var temp= (maxWidth-l)%(size)
             var str='';
             var k=0;
             for(var j=index;j<i;j++){
                 if(j==i-1){
                     if(size===0){
                         str +=words[j]+packSpace(maxWidth-words[j].length);
                     }else{
                         str +=words[j];
                     }

                     break;
                 }
                 if(k<temp){
                     str +=words[j]+packSpace(spaceSize)+' ';
                 }else{
                     str +=words[j]+packSpace(spaceSize)
                 }
                 k++;
             }
             result.push(str);
             index=i;
             // if(i==words.length){break;}
             sum=words[i].length+1;
         }
         ////
         if(i==words.length-1){
             i++;
             var str='';
             for(var j=index;j<i;j++){
                 if(j==i-1){
                  str +=words[j]
                  str+=packSpace(maxWidth-str.length);
                     break;
                 }
                 str+=words[j]+' ';
             }
             result.push(str);
             index=i;
             if(i==words.length){break;}
             sum=words[i].length+1;
         }
     }
     return result;
 };

Palindrome Pairs--leetcode

Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:

Given words = [“bat”, “tab”, “cat”]

Return [[0, 1], [1, 0]]

The palindromes are [“battab”, “tabbat”]

Example 2:

Given words = [“abcd”, “dcba”, “lls”, “s”, “sssll”]

Return [[0, 1], [1, 0], [3, 2], [2, 4]]

The palindromes are [“dcbaabcd”, “abcddcba”, “slls”, “llssssll”]

求一组单词中是一对回文(对称的单词)的下标.

var palindromePairs1 = function(words) {
    var result=[];
    for(var i=0;i<words.length;i++){
        // words[i].CharAt(0)
        loop:
                for(var j=0;j<words.length;j++){
                    if(i===j){continue;}
                    var str=words[i]+words[j];
                    for(var k=0;k<Math.floor(str.length/2);k++)
                    {
                        if(str.charAt(k)!=str.charAt(str.length-1-k)){
                            continue loop;
                        }
                    }
                    result.push([i,j]);
                }
    }
    return result;
};

上面的答案,是超时的。可能原因是,charAt(n)。时间复杂度为O(n)。这里要循环遍历整个字符串。所有以时间复杂度为O(n!)。n越大,操作越多。这里把var str=words[i]+words[j];加大了操作次数。

var palindromePairs = function(words) {
    var result=[];
    for(var i=0;i<words.length;i++){
        // words[i].CharAt(0)
        loop:
                for(var j=0;j<words.length;j++){
                    if(i===j){continue;}
     //               var str=words[i]+words[j];
                    var LongStr;
                    var length;
                    var left;
                    if(words[i].length<words[j].length){
                        length =  words[i].length;
                        LongStr=words[j];
                        left=j;
                    }else{
                        length =  words[j].length;
                        LongStr = words[i];
                        left=i;
                    }

                    for(var k=0;k<length;k++)
                    {
                        if(words[i].charAt(k)!=words[j].charAt(words[j].length-1-k)){
                            continue loop;
                        }
                    }
                    if(left==j){
                        for(var k=0;k<Math.floor((LongStr.length-length)/2);k++)
                        {
                            if(LongStr.charAt(k)!=LongStr.charAt(LongStr.length-length-1-k)){
                                continue loop;
                            }
                        }
                    }else{
                        for(var k=length;k<Math.floor((LongStr.length-length)/2)+length;k++)
                        {
                            if(LongStr.charAt(k)!=LongStr.charAt(LongStr.length+length-k-1)){
                                continue loop;
                            }
                        }
                    }

                    result.push([i,j]);
                }
    }
    return result;
};//Runtime: 1473 ms

这次通过了。

JavaScript——跳多层for循环

科普常识:写一些算法的时候,蛮有用的。

       var num=0;
        for(var i=0;i<10;i++){
            for(var j=0;j<10;j++){
                if(i==5&&j==5){
                    break;
                }
                num++
            }
        }
        console.log(num)  //num==95
//这里代码等于
        var num=0;
        P:
                for(var i=0;i<10;i++){
                    for(var j=0;j<10;j++){
                        if(i==5&&j==5){
                            continue P;     //continue到P;
                        }
                        num++
                    }
                }
        console.log(num)  //num=95


         var num=0;
        P:
        for(var i=0;i<10;i++){
            for(var j=0;j<10;j++){
                if(i==5&&j==5){
                      break P;         //break到P;
                }
                num++
            }
        }
        console.log(num)  //num=55

e.target、e.srcElement、currentTarget、this的使用问题

e.target、e.srcElement:指触发事件的源

  • srcElement是IE下的属性
  • target是Firefox下的属性
  • Chrome浏览器同时有这两个属性

currentTarget、this: 注册的dom

123456789

var cs= document.getElementById(‘cs’)
cs.addEventListener(‘click’,function(e){
console.log(‘e.target’,e.target)
console.log(‘e.srcElement’,e.srcElement)
console.log(‘e.currentTarget’,e.currentTarget)
console.log(‘this’,this)
},false)

按F12看控制台,点击表格。输出如下:

ES6中Set、Map和WeakSet、WeakMap

ES6 新增了几种集合类型,Set、Map 和WeakSet、WeakMap。

Set

Set 是 ES6 新增的有序列表集合,它不会包含重复项。数组可以存放任何类型的数据,不过数据除重需要自己实现。

var set = new Set();
set.add(window);
set.has(window); // true
set.size; // 1
set.add(window);
set.add(1);
set.size; // 2
set.delete(window);
set.has(window); // false
set.clear();
set.size; // 0


注意:
Set 调用 add、has、delete 等方法时对 key 进行的比较,不做类型转换。可以认为使用 === 进行比较,当然也不全是 ===:  
1.Set 中,NaN 只能添加一次(虽然NaN === NaN 返回 false);  
2.Set 中,「-0」和「0 或 +0」可以同时存在,因为符号不一样(虽然 -0 === 0 或 -0 === +0 返回 true);  
Map

Map 是 ES6 新增的有序键值对集合。键值对的 key 和 value 都可以是任何类型的元素。而Object对象会对 key 进行 toString() 操作,这会导致某些 key 会意外覆盖之前的数据;如果 key 本身是一个对象,toString() 也得不到想要的结果,如下:

var o = {};
var key1 = 2;
var key2 = { toString : function() { return 2 } };
var key3 = { x : 1 };
var key4 = { y : 2 };

o[key1] = 1;
o[key2] = 2;
o[key3] = 3;
o[key4] = 4;

最后,对象o只有两个属性。应为会调用toString()方法,或者说String强制转换。

String(key1)==='2'  
String(key2)==='2'  //虽然key2为对象,但是它有toString()方法。因此为'2'。  
String(key3)==='[object Object]'  
String(key4)==='[object Object]'  
String([])===''  
String([2])==='2'  
String([2,3])==='2,3'  
String(NaN)==='NaN'  
String(new Map())==='[object Map]'  
String(new Set())==='[object Set]'  
String(new WeakSet())==='[object WeakSet]'  
//////////////////////////////////////////
typeof (new Set())===  
typeof (new Object())===  
typeof (new Array())===      //其实Array就是Object。是关联数组。  
typeof (new Map())==="object"//都是'Object'  
new Set().constructor===Set  //true  
new Map().constructor===Map  //true  

使用方法:

var map = new Map();  
var key1 = {toString : function() { return 2}};  
var key2 = 2;  
map.set(key1, 1);  
map.set(key2, 2);

map.has(key1); // true  
map.has('2'); // false,类型不同  
map.delete(2);  
map.size; // 1  
map.get(key2); // undefined 
WeakSet

WeakSet 对象中存储的对象值都是被弱引用的, 如果没有其他的变量或属性引用这个对象值, 则这个对象值会被当成垃圾回收掉. 正因为这样, WeakSet 对象是无法被枚举的, 没有办法拿到它包含的所有元素。WeakSet主要用来储存DOM节点,当这些节点从文档移除时,不会引发内存泄漏。

  • 只存储对象类型元素。new WeakSet().add(1)//错误
  • 有add/delete/clear/has三个方法,不能遍历,没有size属性等.
WeakMap

WeakMap 相对于普通的 Map,也是键值对集合,只不过 WeakMap 的 key 只能是非空对象(non-null object)。WeakMap 对它的 key 仅保持弱引用,也就是说它不阻止垃圾回收器回收它所引用的 key。WeakMap 最大的好处是可以避免内存泄漏。一个仅被 WeakMap 作为 key 而引用的对象,会被垃圾回收器回收掉。

WeakMap 拥有和 Map 类似的 set(key, value) 、get(key)、has(key)、delete(key) 和 clear() 方法,但没有 size 属性,也没有任何与迭代有关的方法。

LRU Cache--LeetCode

Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set.

get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.

set(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.

这里直接用JS中的Map数据结构。Map是有顺序的,后加的在在后面。JS中的Map应该不是Hash_Map(unordered_map),应该是TreeMap(红黑树),因为它是有顺序。用Array会超时。这道题用JS实现没啥含量,数据结构不是自己写的。不过ES6的Map确实很有用。在LeetCode上,比很多的语言快。

var LRUCache = function(capacity) {
    this.size=capacity;
    this.map=new Map();

};
LRUCache.prototype.get = function(key) {
    var value= this.map.get(key);

    if(value===undefined){return -1;}else{
        this.map.delete(key)
        this.map.set(key,value)
        return value;
    }
};
LRUCache.prototype.set = function(key, value) {
    if(this.map.has(key)){
        this.map.delete(key)
    }

    this.map.set(key, value);
    if(this.map.size>this.size){
        for(var x of this.map.keys()){
            this.map.delete(x);
            return;
        }
    }
}//Runtime: 200 ms  94.12%

Max Points on a Line(leetcode)

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.

求二维平面上n个点中,最多共线的点数。

思路:选定一个点,分别计算其他点和它构成的直线的斜率,斜率相同的点肯定在同一条直线上。(1.这里可以利用对称性,减少一半的次数,a到b的斜率等于b到a的。2.自己和自己的斜率不用算,把结果的点数+1返回,即可。)

js中的Object和Map是Key-Value,表示映射关系。但是Object(本质为关联数组)的key只能为String(强制转换)。Value可以是Object。而Map(Object-Object)。虽然在key为String时,看起来一样,但是性能有差别,Map明显快。这里用Object要300ms。用Map只要150ms。

var maxPoints = function(points) {
          if(points.length<3){return points.length;}
              function getMost(arr){
         var j=0;
         var map = new Map()
         for(var i=0;i<arr.length;i++){
             if(arr[i]==undefined){continue;}
             if(isNaN(arr[i])){j++;continue;}
             if(arr[i]==-0){x=0}
             if(arr[i]==-Infinity){x=Infinity}
             if(map.get(arr[i])===undefined){
                 map.set(arr[i],[arr[i]])
             }else{
                 map.get(arr[i]).push(arr[i])
             }

         }
         var temp=0;
         map.forEach(function(p){
             if(temp<p.length){
                 temp=p.length;
             }
         })

         return temp+j;
     }
          var ks=[]
          for(var x in points){
              ks.push([]);
          }
          for(var i=0;i<points.length;i++){  //a:
              for(var j=i+1;j<points.length;j++){
                  ks[i][j]=(points[i].y-points[j].y)/(points[i].x-points[j].x);
                  ks[j][i]=(points[i].y-points[j].y)/(points[i].x-points[j].x);
              }
          }
          var sum=[]
          for(var i=0;i<points.length;i++){  //这里可以再优化,放到a:那里计算。
              sum.push(getMost(ks[i]));
          }
          return (function(){
              var max=-1;
              for(var i=0;i<sum.length;i++) {
                  if (max < sum[i]) {
                      max = sum[i]
                  }
              }
              return max;
          })()+1;
      };//Runtime: 148 ms超过100%的javascript