、函数路线图
以下是RTCMultiConnection.js中函数运行过程图:
图1
二、fun38(续)
2.1 fun38.05(续)
1)代码段一
图2
a.) switch
(/Windows/.test(o) && (/Windows (.*)/.test(o) && (a = /Windows (.*)/.exec(o)[1]), o = "Windows"), o)
b.) /Windows/.test(o)
经测试,/Windows/.test(o)是成立的。
c.) a = /Windows (.*)/.exec(o)[1]
图3
注:测试得知,a = /Windows (.*)/.exec(o)[1])为10,exec也是一个匹配函数,exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比 test() 方法以及支持正则表达式的 String 对象的方法更为复杂。
图4
注:所以接下来,return的结果为o为windows,a为10。
2.2 fun38.11
1)本节完整代码
图5
2)代码段一
var b = !1, y = !1;
注:b,y均为false,!1即为0,所以为flase,另外,console.log的复合写法如下:
console.log('b,y: ',b,y);
3)代码段二
["captureStream", "mozCaptureStream", "webkitCaptureStream"].forEach(function(e) { !b && e in document.createElement("canvas") && (b = !0), !y && e in document.createElement("video") && (y = !0) });
注:经测试结果如下:
图6
注:这是一个循环,当为capture时,结果为真。
4)代码段三
var k = [], T = [], P = [], R = []; c.mediaDevices && c.mediaDevices.enumerateDevices && (c.enumerateDevices = function(e) { c.mediaDevices.enumerateDevices().then(e)["catch"](function() { e([]) }) });
结果如下:
图7
注:k,T,R,P为四个空数组,c.mediaDevices是个数组,c.mediaDevices.enumerateDevices是个函数,尽管没有找到。
c.mediaDevices && c.mediaDevices.enumerateDevices也是个函数。
2.3 fun38.12
1)本阶段完整代码
图8
2)代码段一
var E = !1; void 0 !== _ && "getSources" in _ ? E = !0 : c.mediaDevices && c.mediaDevices.enumerateDevices && (E = !0);
注:E为false,经测试,“_”为undefined,所以,后面的就不走了。但实际上后面的走了,不知什么原因?后面打印出的E为true。
图9
3)代码段二
var x = !1, O = !1, M = !1, A = !1, U = !1;
注:定义了几个布尔值为false的变量。
4)代码段三
a();
注:调用了a()函数,a()函数恰好是fun38.08,如下:
图10
分析一下上述代码如下:
a.) if (!E) return void(e && e());
注:E为true,所以不走这句。
b.) 逗号表达式
if (!c.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources && (c.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack)), !c.enumerateDevices && c.enumerateDevices && (c.enumerateDevices = c.enumerateDevices.bind(c)), !c.enumerateDevices) return void(e && e());
注:c.enumerateDevices是个函数,! c.enumerateDevices应为false。如下:
图11
因为是&&连接的,所以这个if不成立,后面就走了。
c.) k = [], T = [], P = [], R = [];var n = {};
注:定义了几个变量。
d.)函数
图12
注:这个函数在a()中没有走,以后走了再说。
5)代码段四
var I = window.DetectRTC || {}; I.browser = e(), o(function(e) { I.browser.isPrivateBrowsing = !!e }), I.browser["is" + I.browser.name] = !0;
a.) var I = window.DetectRTC || {}; I.browser = e(),
注:I是个空数组,但追加了e()之后,就不是了,具体如下:
图13
b.)
o(function(e) { I.browser.isPrivateBrowsing = !!e }),
注:o是个函数,如下:
图14
c.)
I.browser["is" + I.browser.name] = !0;
注:最终的I如下:
图15
注:其中关于浏览器的信息全放进去了,比如版本,浏览器名字等。
2.4 fun38.13
1)本阶段完整代码
图16
2)代码段一
var D = (!!(window.process && "object" == typeof window.process && window.process.versions && window.process.versions["node-webkit"]), !1);
注:这是一个变量,结果为false,因为是逗号表达式,以最后一个为准: !1一定为false。
3)代码段二
["RTCPeerConnection", "webkitRTCPeerConnection", "mozRTCPeerConnection", "RTCIceGatherer"].forEach(function(e) { D || e in window && (D = !0) }),
运行结果如下:
图17
注:D第一个为false,第一个循环执行完后,就变成了true,因为走了一个D=!0,神奇的是console.log('D = !0: ',D = !0);也算给D重定义。这一段代码的意思是,如果e在window中,就把D置为真。
4)代码段三
I.isWebRTCSupported = D, I.isORTCSupported = "undefined" != typeof RTCIceGatherer;
图18
注:这两句是用于判断是否支持webRTC及ORTC的。
5)代码段四
var L = !1; I.browser.isChrome && I.browser.version >= 35 ? L = !0 : I.browser.isFirefox && I.browser.version >= 34 && (L = !0),
注:定义一个变量L为false。I.browser.isChrome为true,I.browser.version >= 35为true。所以L为true。这段代码的意思,如果是谷歌浏览器,且版本在34以上的话,就把L定为true。
6)代码段五
"https:" !== location.protocol && (L = !1), I.isScreenCapturingSupported = L; var N = { isSupported: !1, isCreateMediaStreamSourceSupported: !1 };
注:协议是https,所以"https:" !== location.protocol为false,所以不执行L = !1,所以此时L为true,I.isScreenCapturingSupported=L,就是支持屏幕捕捉。
图19
再定义一个N,两个元素,均为false,如下:
图20
注:这个有意思,初始值为false,后面又对其进行了重新赋值,所以打开为true。