正则匹配问题
^(?![A-Za-z0-9]+$)
匹配演示
依据正则表达式
实例对象 new 命令
js面向对象编程 oop,是目前主流的编程范式,它将真实世界中各种复杂的关系,抽象成为一个个对象,然后由对象之前的分工合作,完成对真实世界的模拟。
对象object ?
对象是单个实物的抽象;对象是一个容器,封装了属性和方法
构造函数
js里面没有类这个概念,但是我们可以直接通俗的把构造函数理解成为类这个概念,用来生成实例对象的函数,一个构造函数可以生成多个实例对象,这些实例对象都有相同的结构。
构造函数是一个普通的函数,但是它要具有自己的特征和用法
构造函数的首字母需要大写,而字符串则采用驼峰命名法
var Vehicle = function () { this.price =1000; };
在之上的代码中,Vehicle 就是构造函数 ,函数体内部使用了this关键字,代表了要生成的关键字
new命令
使用new
命令时,它后面的函数依次执行下面的步骤。
-
创建一个空对象,作为将要返回的对象实例。
-
将这个空对象的原型,指向构造函数的
prototype
属性。 -
将这个空对象赋值给函数内部的
this
关键字。 -
开始执行构造函数内部的代码。
也就是说,构造函数内部,this
指的是一个新生成的空对象,所有针对this
的操作,都会发生在这个空对象上。构造函数之所以叫“构造函数”,就是说这个函数的目的,就是操作一个空对象(即this
对象),将其“构造”为需要的样子。
如果构造函数内部有return
语句,而且return
后面跟着一个对象,new
命令会返回return
语句指定的对象;否则,就会不管return
语句,返回this
对象。
this关键词
this它总是返回一个对象
this.property
上例中,this代表property属性当前所在对象
总结一下,JavaScript 语言之中,一切皆对象,运行环境也是对象,所以函数都是在某个对象之中运行,this
就是函数运行时所在的对象(环境)
实质
JavaScript语言之所以有this的设计,这跟内存里面的数据结构有很大的关系
var obj = { foo :5}
上面的代码将一个对象赋值给你obj。JavaScript引擎会先在内存里面,生成一个对象{ foo :5},然后把这个对象的内存地址赋值给变量obj。也就是说,变量obj是一个地址(reference)。后面如果要读取obj.foo,引擎先从obj内拿到内存的地址,然后再从这个内存地址中读出原始的对象,返回它的foo属性。
如果this
所在的方法不在对象的第一层,这时this
只是指向当前一层的对象,而不会继承更上面的层。
var a = { p: 'Hello', b: { m: function() { console.log(this.p); } } }; a.b.m() // undefined
上面代码中,a.b.m
方法在a
对象的第二层,该方法内部的this
不是指向a
,而是指向a.b
,因为实际执行的是下面的代码。
var b = { m: function() { console.log(this.p); } }; var a = { p: 'Hello', b: b }; (a.b).m() // 等同于 b.m()
如果要达到预期效果,只有写成下面这样。
var a = { b: { m: function() { console.log(this.p); }, p: 'Hello' } };
如果这时将嵌套对象内部的方法赋值给一个变量,this
依然会指向全局对象。
var a = { b: { m: function() { console.log(this.p); }, p: 'Hello' } }; var hello = a.b.m; hello() // undefined
上面代码中,m
是多层对象内部的一个方法。为求简便,将其赋值给hello
变量,结果调用时,this
指向了顶层对象。为了避免这个问题,可以只将m
所在的对象赋值给hello
,这样调用时,this
的指向就不会变。
var hello = a.b; hello.m() // Hello
一个解决方法是在第二层改用一个指向外层this
的变量。
var o = { f1: function() { console.log(this); var that = this; var f2 = function() { console.log(that); }(); } } o.f1() // Object // Object
上面代码定义了变量that
,固定指向外层的this
,然后在内层使用that
,就不会发生this
指向的改变。
事实上,使用一个变量固定this
的值,然后内层函数调用这个变量,是非常常见的做法,请务必掌握。
JavaScript 提供了严格模式,也可以硬性避免这种问题。严格模式下,如果函数内部的this
指向顶层对象,就会报错。
var counter = { count: 0 }; counter.inc = function () { 'use strict'; this.count++ }; var f = counter.inc; f() // TypeError: Cannot read property 'count' of undefined
上面代码中,inc
方法通过'use strict'
声明采用严格模式,这时内部的this
一旦指向顶层对象,就会报错。
闭包
一个函数和对其周围状态(词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包可以让你在一个内层函数中访问到其他函数外层的作用域,在js中,每当你创建一个函数,闭包就会在函数创建的同时被创建出来。
变狼作用域
分为两种:全局作用域和局部作用域
函数内部可以读取全局变量
let code = 200; function f1(){ console.log(code); } f1(); //200
函数内外部无法读取函数内部的局部变量
function f1(){ let code =200; }
闭包一定是两个函数不是一个函数
箭头函数
箭头函数在普通对象中,正常的this绑定在执行函数的过程中,箭头函数既是在我们的一开始就给出定义
var code = 404, let status = { code :200, getCode:function(){ return function(){ return this.code; }; }; };
行status.getCode()时,返回函数,status.getCode()()表示执行当前返回的函数,其调用者为全局变量window,所以this.code为绑定在window中的code,值为404。
定时器
JavaScript 提供定时代码执行功能,叫做定时器(timer),主要由setTimeout()和setInteral()这两个函数来完成。它们向任务队列添加定时任务。
setTimeout()
setTimeout函数用来指定某个函数或者某个代码,在多少毫秒子后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
var timerId =setTimeout(func|code,delay);
上面的代码中,setTimeout函数接受两个参数,第一个参数func|code是将要推迟执行的函数名或者一段代码,第二个参数delay是推迟执行的毫秒数。
console.log(1); setTimeout('console.log(2)',1000); console.log(3); // 1 // 3 // 2
setInterval()
setInterval 函数的用法与setTimeout 完全一致,区别仅仅在于setInterval指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行。
var i = 1 var timer =setInterval(function(){ console.log(2); },1000)
上面代码中,每隔1000毫秒就输出一个2,会无限的运行下去,知道窗口关闭。
与setTimeout一样,除了前两个参数,setInterval方法还可以接受更多的参数,setInterval会传入回调函数。
clear TImeout(),claerInterval()
setTImeout和setInterval函数,就可以取消对应的定时器。
var id1 = setTimeout(f,1000); var id2 = setIntervl(f,1000); clearTimeout(id1); claerInterval(id3);
上面代码中,回调函数发布会被执行了,